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

Advertisements

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.

>Solution :

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>

Leave a ReplyCancel reply