yqbk
yqbk

Reputation: 726

The difference between setting a new state and changing the old state using setState

I am trying to set the value of one of the keys of the state in my component. The state looks like that:

this.state = {
        stateValue1: false,
        stateValue2: false,
        stateValue3: false
    };

To change my state I use the function:

 handleSwitch = type => {

    this.setState((prevState, type) => ({
        ...prevState,
        [type]: !prevState[type]
    }));

};

Depending on which key of the state I would like to change I use it like:

handleSwitch("stateValue2")

But as the result I get

    {
        stateValue1: false,
        stateValue2: false,
        stateValue3: false
        [object Object]: true
    }

However, when I am using the new object as an argument of setState function everything works fine. Why?

Working code:

handleNotificationSwitch = type => {
    const newState = {
        ...this.state,
        [type]: !this.state[type]
    };

    this.setState(newState);
};

And its result:

    {
        stateValue1: false,
        stateValue2: true,
        stateValue3: false
    }

Upvotes: 1

Views: 1485

Answers (3)

Dave Meehan
Dave Meehan

Reputation: 3201

The second argument to the updater function is the components current props, an object. React setState Docs

I suspect you want something more like the following, assuming type is a prop:

handleSwitch = type => {

    this.setState((prevState, props) => ({
        ...prevState,
        [props.type]: !prevState[props.type]
    }));

};

Or, you were intending to use the type parameter passed to handleSwitch, in which case:

handleSwitch = type => {

    this.setState((prevState, props) => ({
        ...prevState,
        [type]: !prevState[type]
    }));

};

Upvotes: 1

Denys Kotsur
Denys Kotsur

Reputation: 2599

According to docs an updater function of setState accept two params, second is props. So, actually, you're setting props to state.

Upvotes: 3

Ben West
Ben West

Reputation: 4596

Remove or rename the second argument from the function you pass to setState.

this.setState( prevState => ({
    ...prevState,
    [type]: !prevState[type]
}));

or

this.setState( ( prevState, props ) => ({
    ...prevState,
    [type]: !prevState[type]
}));

The type argument passed to handleSwitch is the value you want - inside setState, type is set to whatever React passes to that function, which is props.

Upvotes: 1

Related Questions