Ist there a way to pass data from child to parent using Hooks?

Viewed 9961

As an absolute newbie to React, I'd like to pass data from a child to parent component. But if I look for this question, I always find the "old" way using "state" and "callback" functions. See for example this article: https://medium.com/@ruthmpardee/passing-data-between-react-components-103ad82ebd17

Since all the guides use the traditional way, I'm very confused because they look so different from what I know. For example, instead of using "this.state" in the constructor, I use the useState() Hook.

Is there any way or maybe Hook I don't see that makes it possible to pass data from a child to a parent component?

3 Answers

There is no difference in flow between Functional and Class Component. You can update the value of the parent by passing the function with props and using it at the child.

parent.js

import React, {useState} from 'react';

const Parent = () => {
    const [counter, setCounter] = useState(0);

    return (
        <Child updateCounter={setCounter}>

        </Child>
    )

}

child.js

const Child = (props) => {
    const {updateCounter} = props;

    return (
        <button onClick={() => updateCounter(some value)}>

        </button>
    )
}

Imagine that you have a parent component App that has the logic for handling the submit (could be any other kind of logic) of a form that is a child component of App.

The ChildForm has a local state to store its inputValue.

When you click the submit function, it will call a function onSubmit from the parent App and it will pass along its inputValue (you can pass any other value that it's present inside the component) to be processed and submitted, in this example.

So the gist of it, is:

  • Send a function from the parent to the child as props
  • The child will call that function sending some data as parameters
  • That function will handle the data and can trigger some action from the parent, for example

See snippet below:

function App() {
  
  function onSubmit(formState) {
    console.log('I will submit my ChildForm Input State: ' + formState);
  }
  
  return(
    <ChildForm
      onSubmit={onSubmit}
    />
  );
}

function ChildForm(props) {
  const [inputValue,setInputValue] = React.useState('');
  
  function onChange() {
    setInputValue(event.target.value);
  }
  
  return(
    <React.Fragment>
    <div>I am ChildForm</div>
    <input type='text' value={inputValue} onChange={onChange}/>
    <button onClick={()=>props.onSubmit(inputValue)}>Click to Submit through parent App</button>
    </React.Fragment>
  );
}

ReactDOM.render(<App/>, document.getElementById('root'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.3/umd/react-dom.production.min.js"></script>
<div id="root"></div> 

You will need to pass functions as props from the parent component to the child in order to pass data up the tree

function Child({ num, onNumClick }) {
  return <span onClick={() => onNumClick(num)}>{num}</span>;
}

function Parent() {
  const [numList] = useState([1, 2, 3, 4, 5]);
  const [clickedItem, setClickedItem] = useState(null);

  const onNumClick = num => setClickedItem(num);

  return (
    <div className="App">
      {numList.map(n => (
        <Child num={n} onNumClick={onNumClick} />
      ))}
      {clickedItem && <p>You clicked on {clickedItem}</p>}
    </div>
  );
}

sandbox

Related