admin管理员组

文章数量:1290927

I have two React ponents, Parent and Child. Both must be function ponents. 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.

I've tried creating a ref in Parent and passing it down to child, but this causes an error. I considered forwardRef() but I'm not sure that will work either.

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 ponents cannot be given refs. Attempts to access this ref will fail. Did you mean to use React.forwardRef()?`

I have two React ponents, Parent and Child. Both must be function ponents. 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.

I've tried creating a ref in Parent and passing it down to child, but this causes an error. I considered forwardRef() but I'm not sure that will work either.

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 ponents cannot be given refs. Attempts to access this ref will fail. Did you mean to use React.forwardRef()?`

Share Improve this question edited Aug 13, 2019 at 15:43 tomasina asked Aug 13, 2019 at 13:31 tomasinatomasina 431 silver badge6 bronze badges 1
  • 1 try onClick={closeChild} ( no prenthesis) – Taki Commented Aug 13, 2019 at 13:35
Add a ment  | 

3 Answers 3

Reset to default 5

Only stateful React ponents can expose the ref automatically. If using functional ponent, I think you'll need to use forwardRef for the child ponent: e.g.

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

From the docs,

Refs provide a way to access DOM nodes or React elements created in the render method.

refs are not meant for changing the state.

You actually need useState in parent ponent, and later you can manage it from child ponent.

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

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. They are useful for:

1.Managing focus, text selection, or media playback.

2.Triggering imperative animations.

3.Integrating with third-party DOM libraries.

https://reactjs/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

本文标签: javascriptReact refs when parent and child are function componentsStack Overflow