我有两个React组件,Parent和Child。两者都必须是功能组件。我正在尝试将孩子的状态从父母更改为孩子。我相信做到这一点的最佳方法是使用引用,但我一直无法使其正常工作。
我尝试在Parent中创建一个ref并将其传递给child,但这会导致错误。我考虑过forwardRef(),但不确定是否也可以。
const Parent = () => {
const ref = React.useRef();
const closeChild = () => {
ref.current.setOpen(false);
};
return (
<div>
<Child ref={ref} onClick={closeChild} />
</div>
);
};
const Child = () => {
const [open, setOpen] = useState(false);
return (
<div>
{open ? <p>open</p> : <p>closed</p>}
</div>
);
};
现在的代码会产生此错误消息:
react-dom.development.js:506警告:无法为功能组件提供引用。尝试访问此引用将失败。您是要使用React.forwardRef()吗?
答案 0 :(得分:1)
只有statefull React组件会自动公开ref。如果使用函数,我认为您需要对子组件使用forwardRef: 例如
const FancyButton = React.forwardRef((props, ref) => (
<button ref={ref} className="FancyButton">
{props.children}
</button>
));
// You can now get a ref directly to the DOM button:
const ref = React.createRef();
<FancyButton ref={ref}>Click me!</FancyButton>;
答案 1 :(得分:1)
我认为您在这里不需要裁判,您应该真正避免使用它们。
避免将refs用于可以声明式完成的任何事情。它们可用于:
1。管理焦点,文本选择或媒体播放。
2。触发命令性动画。
3。与第三方DOM库集成。
https://reactjs.org/docs/refs-and-the-dom.html
为什么不仅仅通过道具将价值发送给孩子?
const A&&
const Parent = () => {
const [open] = useState(false);
const toggleChild = () => {
this.setState(prevState => {open: !prevState.open});
};
return (
<div>
<Child onClick={toggleChild} open={this.state.open}/>
</div>
);
};
编辑:忘记了您正在使用钩子。这样的话
const Child = (props) => {
return (
<div>
{props.open ? <p>open</p> : <p>closed</p>}
</div>
);
};
编辑2:@ ravibagul91指出,您还需要将onClicks放在子const [open, setOpen] = useState(false);
const toggleChild = () => {
setOpen(!open);
};
return (
<div>
<Child onClick={toggleChild} open={open}/>
</div>
);
元素中,看看他的回答
答案 2 :(得分:1)
从docs,
引用提供了一种方法,可以访问在render方法中创建的DOM节点或React元素。
refs
并不用于更改state
。
您实际上在父组件中需要useState
,以后可以从子组件中对其进行管理。
const Parent = () => {
const [open, setOpen] = useState(true);
const toggleChild = () => {
setOpen(!open)
};
return (
<div>
<Child onClick={toggleChild} open={open}/>
</div>
);
};
const Child = (props) => {
return (
<div>
{props.open ? <p onClick={props.onClick}>open</p> : <p onClick={props.onClick}>closed</p>}
</div>
);
}