Search code examples
javascriptreactjsweb-frontend

Is there a better way to call a child function from a parent component in React, other than this?


I tried to call a function in a child component from a parent component in React, but without the use of refs, and i succeeded but i don't know if my way is something other than a cheap hack. What can be a better way to do this?

I'm also reading the docs but i may have missed the right way. Any resource suggestion and idea is appreciated.

My parent code:

function Parent(props){ 
  const [submitClicked, setSubmitClicked] = useState(false);
  function onSubmitClick(e){
    e.preventDefault();
    setSubmitClicked(true);
  }

  return (
    <Child 
      submitClicked={submitClicked}
      setSubmitClicked={setSubmitClicked}
    />
  );
}

Child code:

function Child(props) {
  useEffect(()=>{
    if(props.submitClicked){

      //do something in the child component...

      props.setSubmitClicked(false);
    }
  });
}

Solution

  • Pass down a handler (a function) to the child component from the parent that deals with the state updates.

    const { useState } = React;
    
    // Child receives the handler
    // When the button is clicked call the handler
    function Child({ handleSubmit }) {
      return <button onClick={handleSubmit}>Click me</button>
    }
    
    function Parent() {
    
      const [ submitClicked, setSubmitClicked ] = useState(0);
    
      // The handler deals with the state update
      function handleSubmit() {
        setSubmitClicked(submitClicked + 1);
      }
    
      return (
        <div>
          <p>{submitClicked}</p>
          <Child handleSubmit={handleSubmit} />
        </div>
      );
    };
    
    // Render it
    ReactDOM.render(
      <Parent />,
      document.getElementById("react")
    );
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.1/umd/react.production.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.1/umd/react-dom.production.min.js"></script>
    <div id="react"></div>