Rachel
Rachel

Reputation: 727

Setting state within a React method

I have a React component that passes a value (e) into a filter, e will always be one of these values: {true, false, SHOW_ALL}.

filterItem(e) {  
    this.state.filter[0].Status = e.target.value;
    this.setState({
         filter: this.state.filter
    });
 }

React is complaining that I am modifying state directly. Getting this warning: Do not mutate state directly. Use setState()

I can't figure out how to set the filter status to the e.target.value, AND include in the assign inside setState(); To set the status I have to assign e.target.value to the Status property like so:

 this.state.filter[0].Status = e.target.value;

Upvotes: 1

Views: 102

Answers (4)

Jonas Wilms
Jonas Wilms

Reputation: 138257

Thats actually a bit complicated:

this.setState(previous => ({
     filter: [{
        ...previous.filter[0],
        Status: e.target.value
     }].concat(previous.filter.slice(1))
}));

PS: This is one of the cases were i would prefer simplicity over strict state transitions, so just ignore the warning ;)

Upvotes: 0

Shea
Shea

Reputation: 308

filterItem(e) {
    this.setState({
        filter: e.target.value
    });
}

this.state.filter[0].Status = e.target.value; is mutating the state directly. You are directly assigning a value to the state, rather than using the provided setState() function. This violates one of React's 3 key principles, as stated in the warning you got.

Another thing to note: Status is a reserved word, so you shouldn't use it as a property name.

Also, this.state.filter[0].Status implies that this.state.filter is an array, and you are changing the property Status of its first element. Unless this.state.filter needs to hold multiple elements/items, each with their own Status property, you can just keep it as this.state.filter.

If that was intentional, then you can change the function to this:

filterItem(e) {
    this.setState({
        filter: [{Status: e.target.value}]
    });
}

Upvotes: 2

Aliaksandr Sushkevich
Aliaksandr Sushkevich

Reputation: 12364

First, you need to create a copy of your existing array

const filter = [...this.state.filter]

then you can mutate this copy

filter[0].Status = e.target.value;

and then you can use setState

this.setState({filter: filter})

Upvotes: 1

Piyush Zalani
Piyush Zalani

Reputation: 3934

Instead of assigning it directly like so:

this.state.filter[0].Status = e.target.value;

You can do something like this.

this.setState({filter: [{status: e.target.value}] })

Upvotes: 0

Related Questions