我有两个组件。父母和孩子。
在父组件中,我有一个按钮。如果用户单击该按钮,我想对子组件内的另一个按钮执行滚动查看。
我想我想定义一个对儿童按钮的引用,以便我在父按钮内单击可以做一个:
ref.scrollIntoView({block: 'end', behavior: 'smooth'});
这将滚动到子组件中的按钮。
下面是一个缩小的示例:
ParentComponent.jsx
import React, {useRef} from 'react';
import ChildComponent from './ChildComponent';
const ParentComponent = props => {
const childReference = useRef(null);
const onClick = () => {
childReference.scrollIntoView({block: 'end', behavior: 'smooth'});
}
return (
<>
<...some other components>
<Button onClick={onClick}>Click me to be forwarded</Button>
<ChildComponent ref={childReference}/>
</>
);
};
ChildComponent.jsx
import React from 'react';
const ChildComponent = (props, ref) => {
const { name, value, description } = props;
return (
<...some other components>
<Button ref={ref}>You should be forwarded to me</Button>
);
};
ChildComponent.propTypes = {
name: PropTypes.string.isRequired,
value: PropTypes.number,
description: PropTypes.string,
};
ChildComponent.defaultProps = {
value: 0,
description: '',
};
export default React.forwardRef(ChildComponent);
我知道上面的代码不起作用,这只是为了说明我想要实现的目标。
我真的尝试了通过谷歌搜索找到的所有其他解决方案,它们看起来都很容易,但它们似乎都不适合我的用例。我也尝试过使用 forwardRef,但这也不能为我解决它。
更新
我想我对什么不起作用有点模糊。我在实现中收到了很多不同的错误消息。
以下是其中之一:
不能为函数组件提供引用。尝试访问此引用将失败。你的意思是使用 React.forwardRef(( 吗?
溶液
好。我想我会用@Vencovsky提供的解决方案在这里组装这些部件。
这是问题中看到的两个示例组件的完整实现:
ParentComponent.jsx
import React, { useRef } from 'react';
import ChildComponent from './ChildComponent';
const ParentComponent = props => {
const childReference = useRef(null);
const scrollIntoView = () => {
childReference.current.scrollIntoView({block: 'center', inline: 'center', behavior: 'smooth'});
}
return (
<>
<...some other component>
<Button onClick={scrollIntoView}>Click me to be forwarded</Button>
<ChildComponent ref={childReference}
</>
);
};
export default ParentComponent;
ChildComponent.jsx
import React, {forwardRef} from 'react';
import PropTypes from 'prop-types';
const ChildComponent = forwardRef((props, ref) => {
const { name, value, description } = props;
return(
<>
<...some other components>
<Button ref={ref}>You should be forwarded to me</Button>
</>
);
});
ChildComponent.propTypes = {
name: PropTypes.string.isRequired,
value: PropTypes.number,
description: PropTypes.string,
};
ChildComponent.defaultProps = {
value: 0,
description: '',
};
export default ChildComponent;
编辑 2:
我猜你正在做类似的事情
const ChildComponent = (props, ref) => { ... }
ChildComponent.propTypes = { ... }
export default React.forwardRef(ChildComponent)
但是你需要做的是在React.forwardRef
之后传递propTypes
,如下所示:
const ChildComponent = (props, ref) => { ... }
const ForwardComponent = React.forwardRef(ChildComponent)
ForwardComponent.propTypes = { ... }
export default ForwardComponent
更好的方法是
// using forwarRef
const ChildComponent = React.forwarRef((props, ref) => {
const { name, value, description } = props;
return (
<...some other components>
<Button ref={ref}>You should be forwarded to me</Button>
);
});
这样,您无需更改propTypes
并创建另一个组件。
编辑:
作为您的编辑,我可以看到您忘记使用React.forwardRef
.
您应该添加
export default React.forwardRef(ChildComponent)
到您的ChildComponent
文件(使用 forwardRef 导出(。
什么不起作用?您收到错误吗?你应该更好地解释发生了什么,但我会试着猜测。
有些东西可以使它不起作用。
- 您需要使用
ref.current.foo
而不是ref.foo
- 正如@JeroenWienk所说:
似乎您的按钮也是一个自定义组件。您确定引用正在传递给其中的 html 按钮元素吗?
- 要使用功能组件的第二个参数,您应该使用
React.forwardRef
。 例如export default React.forwardRef(ChildComponent)