AnswerBun.com

React: useState value doesn't update on parameter value change

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

3 Answers

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

Add your own answers!

Related Questions

How to get records ordered by joined table field

2  Asked on December 16, 2021 by jaime

 

how to display input using button in right to left order?

5  Asked on December 16, 2021 by mr-josh

       

Kotlin Image Compression Implementation

1  Asked on December 16, 2021 by android

       

Finding a cover of a set of points with circles

2  Asked on December 16, 2021 by user577545

   

Pytorch: all-but-one summation?

3  Asked on December 16, 2021 by sterne

   

Is it okay to mark @Input() as private or readonly?

2  Asked on December 16, 2021 by natoboram

   

Linking URL in JavaScript

2  Asked on December 16, 2021 by vuk-stamenkovic

   

Making a 2×2 grid in Flutter

2  Asked on December 16, 2021 by zerok

   

Uniform tick labels for non-linear colorbar in Matplotlib

1  Asked on December 16, 2021 by marie-eve-lb

     

Custom Javadoc not showing in IDE

1  Asked on December 16, 2021 by hugo-bois

       

Ask a Question

Get help from others!

© 2023 AnswerBun.com. All rights reserved. Sites we Love: PCI Database, MenuIva, UKBizDB, Menu Kuliner, Sharing RPP, SolveDir