HiveBrain v1.2.0
Get Started
← Back to all entries
patternreactCritical

React.useState does not reload state from props

Submitted by: @import:stackoverflow-api··
0
Viewed 0 times
usestatepropsfromdoesreactreloadstatenot

Problem

I'm expecting state to reload on props change, but this does not work and user variable is not updated on next useState call, what is wrong?

function Avatar(props) {
  const [user, setUser] = React.useState({...props.user});
  return user.avatar ? 
         ()
        : (Loading...);
}


codepen

Solution

I've seen almost all the answers to this question promoting a bad pattern: updating state as a result of a prop change inside a useEffect call. The useEffect hook is used for synchronizing your React components with external systems. Using it for synchronizing React states can potentially lead to bugs (because re-renders caused by other effects can lead to unintended state updates). A better solution would be to trigger a reconciliation with a key prop change in the ` component from its parent:

// App.jsx
function App() {
   // ...logic here
   return 
}

// Avatar.jsx
function Avatar({ initialUser }) {
 // I suppose you need this component to manage it's own state 
 // otherwise you can get rid of this useState altogether.
  const [user, setUser] = React.useState(initialUser);
  return user.avatar ? (
    
  ) : (
    Loading...
  );
}


You can think of that
key prop in this case as the dependency array of useEffect, but you won't be triggering unintended state changes as a result of unexpected useEffect calls triggered by the component renders.

You can read more about this here:
Putting Props To State

And more info on how
useEffect` might be a foot gun, here:

You Might Not Need an Effect

Code Snippets

// App.jsx
function App() {
   // ...logic here
   return <Avatar initialUser={user} key={user.id} />
}

// Avatar.jsx
function Avatar({ initialUser }) {
 // I suppose you need this component to manage it's own state 
 // otherwise you can get rid of this useState altogether.
  const [user, setUser] = React.useState(initialUser);
  return user.avatar ? (
    <img src={user.avatar} />
  ) : (
    <p>Loading...</p>
  );
}

Context

Stack Overflow Q#54865764, score: 111

Revisions (0)

No revisions yet.