React Hook : Send data from child to parent component

Kaherdin picture Kaherdin · Apr 17, 2019 · Viewed 60.3k times · Source

I'm looking for the easiest solution to pass data from a child component to his parent.

I've heard about using Context, pass trough properties or update props, but I don't know which one is the best solution.

I'm building an admin interface, with a PageComponent that contains a ChildComponent with a table where I can select multiple line. I want to send to my parent PageComponent the number of line I've selected in my ChildComponent.

Something like that :

PageComponent :

<div className="App">
  <EnhancedTable />         
  <h2>count 0</h2>
  (count should be updated from child)
</div>

ChildComponent :

 const EnhancedTable = () => {
     const [count, setCount] = useState(0);
     return (
       <button onClick={() => setCount(count + 1)}>
          Click me {count}
       </button>
     )
  };

I'm sure it's a pretty simple thing to do, I don't want to use redux for that.

Answer

Tholle picture Tholle · Apr 17, 2019

A common technique for these situations is to lift the state up to the first common ancestor of all the components that needs to use the state (i.e. the PageComponent in this case) and pass down the state and state-altering functions to the child components as props.

Example

const { useState } = React;

function PageComponent() {
  const [count, setCount] = useState(0);
  const increment = () => {
    setCount(count + 1)
  }

  return (
    <div className="App">
      <ChildComponent onClick={increment} count={count} />         
      <h2>count {count}</h2>
      (count should be updated from child)
    </div>
  );
}

const ChildComponent = ({ onClick, count }) => {
  return (
    <button onClick={onClick}>
       Click me {count}
    </button>
  )
};

ReactDOM.render(<PageComponent />, document.getElementById("root"));
<script src="https://unpkg.com/react@16/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>

<div id="root"></div>