Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

componentDidUpdate called twice every route change

In my application i have a HomePage component which has navlinks in it. the route for this component is <Route to="/browse/:item" exact component={HomePage} />. so the component has a navigation bar with NavLink links to "sub routes" of it. for example a NavLink that leads you to /browse/featured or /browse/new and i added to this component the lifecycle method componentDidUpdate() to just console.log("UPDATED HOMEPAGE") and whenever i click a NavLink this happens:

i tried to use shouldComponentUpdate with the nextProps and nextState params to see if indeed the state or props are changed (something that will cause a re-render) but they stay the same. Thanks in advance for your help.

EDIT: the code is on github https://github.com/idanlo/spotify-test-frontend components that have the problem that i have seen are AlbumView and HomePage

ANOTHER EDIT: updates this is a console.log() of the two updates happening, each one displaying the props before and after the update. on the first update you can see that the url is different so the update is supposed to happen but on the second update nothing is different, everything is the same (in the state everything is the same too)

like image 669
Idan Lottan Avatar asked Jul 21 '18 17:07

Idan Lottan


Video Answer


2 Answers

Usually there are multiple calls because of changes made to the state. Check other files to make sure that no actions that modify the state are initially called. Even though you check for differences for nextProps, the variable that changes might not be in props.

like image 101
HunterLiu Avatar answered Sep 30 '22 10:09

HunterLiu


I suspect that Navlink's internal implementation uses setState with an updater function which is the source of this duplicate log

I found that when I update state with an updater function then componentDidUpdate gets fired twice!

However when I pass an object to setState - componentDidUpdate is fired only once.

setState(updater[, callback])

example:

incrementScore = () => {
this.setState(prevState => ({
    score: prevState.score + 1
  }));
};

VS

setState(stateChange[, callback])

example:

this.setState({quantity: 2})

I guess it's because

Think of setState() as a request rather than an immediate command to update the component. For better perceived performance, React may delay it, and then update several components in a single pass. React does not guarantee that the state changes are applied immediately.

read about setState on React Docs

like image 24
Bar Horing Amir Avatar answered Sep 30 '22 09:09

Bar Horing Amir