2

My code is this:

handleFavourite = id => {
    const { restaurants } = this.state;
    let newRestaurants = [...restaurants];
    newRestaurants = sort(newRestaurants, 'favourite');
    console.log(newRestaurants); // ALL GOOD
    this.setState({ restaurants: newRestaurants }, () => console.log(this.state.restaurants)); // CONSOLE LOG POSTS OLD DATA
};

So there. The callback function in setState shows old data and in UI nothing gets sorted as well. Why is it that way?

edit: Found the problem. I'm also using static getDerivedStateFromProps and it's resetting the state every time.

Xeen
  • 6,955
  • 16
  • 60
  • 111
  • Reproducible example please, [How to create a Minimal, Reproducible Example](https://stackoverflow.com/help/minimal-reproducible-example) – Dennis Vash Oct 12 '19 at 10:39

3 Answers3

1

I'd be checking this.state.restaurants in componentDidUpdate as that's the best way to see if your component has been updated.

It feels like you're doing things correctly if your first log is indeed correct (it seems an odd way to sort to me, I'd be calling array.sort() on the newRestaurants).

Maybe somewhere after your component updates, something is setting the restaurants back to it's original value again.

dougajmcdonald
  • 19,231
  • 12
  • 56
  • 89
  • `componentDidUpdate` shows updated state for the values that I'm changing in `restaurants`, but it's still not sorted. And the `sort` function in my example is using `array.sort` in the background. – Xeen Oct 12 '19 at 10:44
  • Is it possible you've got something funny going on in your render? what are you using for the `key` value? – dougajmcdonald Oct 12 '19 at 11:05
  • It's often something like that, it's not that you're doing it wrong where you look,it's changing elsewhere where you're not looking! :P Referring to my second paragraph "But maybe somewhere after your component updates, something is setting the restaurants back to it's original value again." – dougajmcdonald Oct 12 '19 at 19:05
0

handleFavourite seems to work a O.K.

class App extends React.Component {
  state = {
    restaurants: ["a", "b", "c"]
  }
  
  handleFavourite = id => {
    const { restaurants } = this.state;
    let newRestaurants = [...restaurants];
    newRestaurants = sort(newRestaurants, 'favourite');
    console.log(newRestaurants); // ALL GOOD
    this.setState({ restaurants: newRestaurants }, () => console.log(this.state.restaurants)); // CONSOLE LOG POSTS OLD DATA
}

render() {
  const restaurants = this.state.restaurants.map(r => <p>{r}</p>)
  return (
    <div>
      {restaurants}
    <hr/>
    <button onClick={this.handleFavourite}>sort</button>
    </div>
  )
}
}

function sort(r) {
  return r.reverse();
}

ReactDOM.render(<App/>, document.getElementById("root"))
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id="root"></div>
marzelin
  • 10,790
  • 2
  • 30
  • 49
0
 newRestaurants = sort(newRestaurants, 'favourite'); 
// This mutates the original array and does not create a new copy.

A workaround is to create a new copy using slice function
    newRestaurants = sort(newRestaurants, 'favourite').slice(); 
    this.setState({ restaurants: newRestaurants });
anand k
  • 1
  • 3