当父级和子级是功能组件时,反应引用

时间:2019-08-13 13:31:58

标签: javascript reactjs

我有两个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()吗?

3 个答案:

答案 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>
  );
}

Demo