Jake Kwon
Jake Kwon

Reputation: 317

React-hooks does not update state

Some how match data is from the parent class, and I initialized matches using useState(match) However, matches data is containing old data and wasn't updated as parent match data. Anyone help?

const FixtureDetailItem = ({ type, match, teams, isAdmin, postMatchesStart, putMatchesStart }) => {
  console.log(match)
  const [matches, setMatches] = useState(match);
  const { homeTeamId, homeTeamName, homeScore, awayTeamId, awayTeamName, awayScore, scheduledAt, location, league, matchRecords} = matches;

  useEffect(() => {
    console.log('fired')
    console.log(matches)
    setMatches(matches)
  }, [matches]);

Upvotes: 1

Views: 159

Answers (1)

Richard Matsen
Richard Matsen

Reputation: 23463

There seems to be a circular connection between useEffect() and the useState - useEffect has a dependency of matches, then sets matches.

If you want it to change when match changes, then match should be the dependency.

Note that useState(match) only fires on the very first render. On subsequent renders, you must use setMatches() to change the value of matches.

const FixtureDetailItem = ({ type, match, ... }) => {

  const [matches, setMatches] = useState(match);
  const { ... } = matches;

  useEffect(() => {
    setMatches(match)
  }, [match]);

  ... // JSX here

}

@James I though this might need some clarification.

See my statement above - useState(match) only fires on the very first render.

On first render useState(match) sets matches equal to match.

Then the parent changes match, and because the match prop changed, the FixtureDetailItem function runs again, but React does not run useState(match) for the new value (by design).

It considers matches to be internal state of this component and leaves it with the old value.

Since matches does not change, the effect will not run - it only runs when one of it's dependencies change.

Upvotes: 1

Related Questions