简体   繁体   English

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

[英]React refs when parent and child are function components

I have two React components, Parent and Child. 我有两个React组件,Parent和Child。 Both must be function components. 两者都必须是功能组件。 I am trying to change the state of Child from Parent. 我正在尝试将孩子的状态从父母更改为孩子。 I believe the best way to do this is using refs, but I haven't been able to get it to work. 我相信做到这一点的最佳方法是使用refs,但我一直无法使其正常工作。

I've tried creating a ref in Parent and passing it down to child, but this causes an error. 我曾尝试在Parent中创建一个ref并将其传递给child,但这会导致错误。 I considered forwardRef() but I'm not sure that will work either. 我考虑过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>
  );
};

The code as it is now produces this error message: 现在的代码会产生以下错误消息:

react-dom.development.js:506 Warning: Function components cannot be given refs. react-dom.development.js:506警告:无法为功能组件提供引用。 Attempts to access this ref will fail. 尝试访问此引用将失败。 Did you mean to use React.forwardRef()?` 您是要使用React.forwardRef()吗?

I don't think you need refs here, you should really try to avoid them. 我认为您在这里不需要裁判,您应该真正避免使用它们。

avoid using refs for anything that can be done declaratively. 避免将ref用于可以声明式完成的任何事情。 They are useful for: 它们可用于:

1.Managing focus, text selection, or media playback. 1.管理焦点,文本选择或媒体播放。

2.Triggering imperative animations. 2.触发命令式动画。

3.Integrating with third-party DOM libraries. 3.与第三方DOM库集成。

https://reactjs.org/docs/refs-and-the-dom.html https://reactjs.org/docs/refs-and-the-dom.html

why not just send the value into the child through props? 为什么不仅仅通过道具将价值传递给孩子呢?

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

EDIT: forgot you were using hooks. 编辑:忘记了您正在使用挂钩。 This is the way then 然后是这样

const [open, setOpen] = useState(false);

  const toggleChild = () => {
    setOpen(!open);
  };

  return (
    <div>
      <Child onClick={toggleChild} open={open}/>
    </div>
  );

EDIT 2: @ravibagul91 pointed out that you need to put the onClicks in the children <p> elements as well, look at his answer 编辑2:@ ravibagul91指出,您还需要将onClicks放在子元素<p> ,看一下他的回答

From the docs , 文档中

Refs provide a way to access DOM nodes or React elements created in the render method. 引用提供了一种访问DOM节点或在render方法中创建的React元素的方法。

refs are not meant for changing the state . refs无意改变state

You actually need useState in parent component, and later you can manage it from child component. 实际上,您在父组件中需要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 演示版

Only statefull React components expose the ref automatically. 只有有状态的React组件会自动公开ref。 If using functional, I think you'll need to use forwardRef for the child component: eg 如果使用函数,我认为您需要对子组件使用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>;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM