Reputation: 7003
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.
Upvotes: 2
Views: 2918
Reputation: 1
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 });
Upvotes: 0
Reputation: 20037
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.
Upvotes: 1
Reputation: 11600
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>
Upvotes: 0