Home > other >  How to pass SetState variable to child component so that it changes when it changes in the parent
How to pass SetState variable to child component so that it changes when it changes in the parent

Time:11-26

I tried to make the simplest example of this here. When you check the box, the parent text Text #1 alternates back and forth from "true" to "false" while the child text Text #2 never changes. I want Text #2 to change just like Text #1 does.

function Parent(props) {
    const [state1, setState1] = useState(true);
    const [currentView, setCurrentView] = useState(<Child checkHandler={checkHandler} state1={state1} />);
    function checkHandler(event) {
        setState1(event.target.checked);
    }
    return (
        <div>
            Text #1: {state1 ? "true" : "false"}
            {currentView}
        </div>
    );
}

export default Parent;

function Child({
    state1,
    checkHandler
}) {
return (
    <div>
        Text #2: {state1 ? "true" : "false"}
        <form>
            <input type="checkbox" id="checkbox" onChange={checkHandler} />
            <label for="checkbox">Check</label>
        </form>
    </div>
  );
}

export default Child;

I've searched for similar answers, but I can't find anywhere a simple explanation on how to do what I think would be a very fundamental thing to do in React Redux.

CodePudding user response:

Component instances should almost never be put into state, because then their props and own state won't update naturally. You need to be calling <Child checkHandler={checkHandler} state1={state1} / whenever the parent re-renders so that when the parent values change, the child can re-render with its new props.

The checkbox is also not checked by default, yet you do const [state1, setState1] = React.useState(true); - better to be consistent. Consider adding the checked prop to the child.

function Parent(props) {
    const [state1, setState1] = React.useState(true);
    function checkHandler(event) {
        setState1(event.target.checked);
    }
    return (
        <div>
            Text #1: {state1 ? "true" : "false"}
            <Child checkHandler={checkHandler} state1={state1} />
        </div>
    );
}

function Child({
    state1,
    checkHandler
}) {
return (
    <div>
        Text #2: {state1 ? "true" : "false"}
        <form>
            <input type="checkbox" id="checkbox" onChange={checkHandler} checked={state1} />
            <label htmlFor="checkbox">Check</label>
        </form>
    </div>
  );
}

ReactDOM.createRoot(document.querySelector('.react')).render(<Parent />);
<script crossorigin src="https://unpkg.com/react@18/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@18/umd/react-dom.development.js"></script>
<div class='react'></div>

CodePudding user response:

No need to put the entire component into the state -- it won't work either. Just give the state variable as a prop to the child.

function Parent(props) {
  const [state1, setState1] = useState(true);
  function checkHandler(event) {
    setState1(event.target.checked);
  }
  return (
    <div>
      Text #1: {state1 ? "true" : "false"}
      <Child checkHandler={checkHandler} state1={state1} />
    </div>
  );
}

export default Parent;

function Child({ state1, checkHandler }) {
  return (
    <div>
      Text #2: {state1 ? "true" : "false"}
      <form>
        <input type="checkbox" id="checkbox" onChange={checkHandler} />
        <label for="checkbox">Check</label>
      </form>
    </div>
  );
}

export default Child;
  • Related