Stack Overflow Asked by darksoulsong on January 5, 2022
In the example below, the value of the display
state on Child component never updates, even if the show
parameter toggles between true and false.
I expect it to receive the value and to update accordingly. Can someone please elaborate on why this is not working?
(I know I can use a useEffect callback and setDisplay(show) from inside it, but I’d like to know why a simpler approach like this doesn’t work)
function Child({ show }) {
const [display] = React.useState(show);
console.log({ show, display });
return display ? "Message!" : null;
}
function Parent() {
const [show, setShow] = React.useState(false);
const handleClick = () => {
setShow(!show);
};
return (
<div>
<div>
<button onClick={handleClick}>Toggle</button>
</div>
<Child show={show} />
</div>
);
}
Working example: https://codesandbox.io/s/react-boilerplate-4hexp?file=/src/index.js
display
is local component state of Child
, given an initial value from props.show
when Child
mounted. There is never a state update within Child
to render any other value of display
. This is actually an anti-pattern to store passed props in local component state, but there are two alternatives/solutions to getting display
to update.
Use an effect to update state when the props update
function Child({ show }) {
const [display, setDisplay] = React.useState(show);
useEffect(() => setDisplay(show), [show]);
console.log(show, display);
return display ? "Message!" : null;
}
Or better, just consume the prop show
directly
function Child({ show }) {
console.log(show);
return show ? "Message!" : null;
}
The benefit of the latter is that the new value of show
and the updated/rerendered UI occur in the same render cycle. With the former (the anti-pattern) the state needs to update then the component rerenders, so the updated UI is a render cycle delayed.
Answered by Drew Reese on January 5, 2022
I believe it's because the useState
in the Child component is reading show
when it first loads but then never updates because it's just set, it doesn't automatically update.
You could either just use show
directly which should be used for return show ? 'message' : <></>
Or you could still use the local state with useState
, but you would need to add a useEffect
to listen to the props change then change the local state of that child.
Update:
Third option for your current code to work would also be to do:
{show && <Child show={show} />}
That way at the time when it's true, the component will read the latest data.
Answered by codingwithmanny on January 5, 2022
Well the value of display is set only on the first render of the component (because it is state and state doesnt change with renders, but only when you tell it to change). If you want it to be changing with changing props just use a normal constant instead.
Answered by Martin Červenka on January 5, 2022
Get help from others!
Recent Answers
Recent Questions
© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP