Morleee
Morleee

Reputation: 347

Can only update a mounted or mounting component. This usually means you called setState() on an unmounted component

I've been trying to invoke a method when a component loads, in order to sort data on the initial page load.

In the example below, I set my state to the initial data, then instantly call the sort() method to sort the data.

export default class Leaderboard extends React.Component {
constructor(){
    super();
    this.state = {
        rows: 
            [{name: "Jonny", points: 124, total: 1234},
            {name: "Bob", points: 321, total: 4321},
            {name: "Sally", points: 234, total: 31234},
            {name: "Katie", points: 613, total: 12333},
            {name: "Cameron", points: 1232, total: 5231}]
    };
    this.sort("daily");
}

sort(args){
    if (args === "daily") {
        var sorted = this.state.rows.sort(function(a, b){
            return a.points-b.points;
        });
        this.setState(sorted.reverse());
    }
    if (args === "total") {
        var sorted = this.state.rows.sort(function(a, b){
            return a.total-b.total;
        });
        this.setState(sorted.reverse());
    }
}
render() {
    const Rows = this.state.rows.map((obj, i) => <Row key={i} num={i} name={obj.name} points={obj.points} total={obj.total}/> );    

    return (
        <div className="col-md-10 col-md-offset-1">
            <table className="table table-hover">
                <tbody>
                    <tr>
                        <th colSpan="4" className="text-center">Leaderboard</th>
                    </tr>
                    <tr>
                        <th> Number </th>
                        <th> Name </th>
                        <th onClick={() => this.sort("daily")}> Points </th>
                        <th onClick={() => this.sort("total")}> All time points </th>
                    </tr>
                    {Rows}
                </tbody>
            </table>
        </div>
    );
}

}

This works, but I'm getting a message in the console:

Warning: setState(...): Can only update a mounted or mounting component. This usually means you called setState() on an unmounted component. This is a no-op. Please check the code for the Leaderboard component.

Can this warning be safely ignored?

Upvotes: 3

Views: 788

Answers (1)

Jack
Jack

Reputation: 21163

This is happening because you're calling this.sort("daily") in your constructor, which is calling this.setState before the component is mounted.

Instead call this.sort("daily") in componentWillMount or componentDidMount.

EDIT

As @robertkelp pointed out you should change your sorting and setState to something like this:

var sorted = this.state.rows.slice(0).sort(function(a, b){
  return a.points-b.points;
});
this.setState({rows: sorted.reverse()});

Note that it's doing slice(0) to clone your array and properly setting state into the rows property.

Upvotes: 3

Related Questions