Reputation: 1929
I have few states like
this.state = {
abc1,
abc2,
abc3
}
Why I can't setState dynamically? like
handleDiscount = (count) => {
this.setState({
`abc${count}`: `!this.state.abc${count}`
});
}
Where count is 1 / 2 / 3.
Upvotes: 1
Views: 760
Reputation: 3996
In order to get property of the target object please use target["string property name"]
bracket syntax.
As for adding dynamic property to object you should use { ["string property name"]: value }
computed property name syntax.
Your fixed code should look like this:
handleDiscount = (count) => {
this.setState({
[`abc${count}`]: !this.state[`abc${count}`]
});
}
Please see working example here.
As a side note, you should really check Linus' answer regarding React's setState
behavior.
Upvotes: 0
Reputation: 39261
The problem is that you are using a template string for an object property declaration; it's a syntax error. Even so, you couldn't set the template string to a variable and use that, either:
let count = 2;
let bar = `baz${count}`;
// This will set foo.bar, not foo.baz2
let foo = {
bar: count
};
What you can do is use ES6 computed property names:
let count = 2;
let bar = `baz${count}`;
// This will set foo[<value of bar>], i.e. foo.baz2
let foo = {
[bar]: count
};
And this also works with template strings:
let count = 2;
// This will set foo[<template string evaluated>], i.e. foo.baz2
let foo = {
[`baz${count}`]: count
};
Also, the template string in your value is wrong. That will not evaluate the property in this.state
, instead, it will be the string e.g. "!this.state.abc2"
. !this.state
is code, not a string. You need this:
!this.state[`abc${count}`]
That being said, whenever setting React state based on the previous state, you should invoke setState with a function instead, from React docs on setState:
[...] If the next state depends on the previous state, we recommend using the updater function form, instead:
this.setState((prevState) => { return {counter: prevState.quantity + 1}; });
So, to summarize, this should do the trick:
handleDiscount = (count) => {
this.setState((prevState) => {
return { [`abc${count}`]: !prevState[`abc${count}`] }
});
};
Upvotes: 2
Reputation: 7657
That's not how you dynamically set object properties. That's template literals.
handleDiscount = (count) => {
this.setState({
abc[count]: !this.state.abc[count]
});
}
But you can't do that with array indexes anyway
Upvotes: -1