I have a state called " show saved". When someone clicks " show saved" I want " show saved" to change to " show hidden". Originally, it worked when I set state to change to " show hidden" onClick:
<p onClick={changeTitle}>
{this.state.saved}
</p>
It called this function:
const changeTitle = () => {
this.setState({ saved:' show hidden' })
}
But now i've added a ternary because I want it to change from " show saved" to " show hidden" back and forth, each time it's clicked. However, now it will not work. Why not?
this.setState({ saved: saved === 'Show saved'? 'Show hidden': 'Show saved'})
How can I fix? Essentially, when a user clicks the state jumps back and forth. Thanks.
CodePudding user response:
You can use an updater function that takes the previous state as the first argument.
this.setState(({saved}) => ({ saved: saved === 'Show saved'? 'Show hidden': 'Show saved'}));
Alternatively store a boolean value and calculate what to display based on that.
this.setState(({saved})=>({saved: !saved}));
<p onClick={changeTitle}>
{this.state.saved ? 'Show saved': 'Show hidden'}
</p>
CodePudding user response:
Functional setState
is the way to go when next state value depends on the previous one. It guarantees that the previous statee value you are using is always accurate.
this.setState((oldSaved) => ({ saved: oldSaved === 'Show saved'? 'Show hidden': 'Show saved'}))
Out of scope, but boolean
is a better type to use for this. You can already see the problem you have when you use a string
for this.
In one code snippet you have written Show Hidden
, and in another show hidden
. This type of bugs will arise and will become difficult to debug. Everywhere you check for this variable you will have to check for the exact correct string (probably use 2 extra variables to ensure that). That is why it is better to use a boolean flag and based on it being true or false, render the value and do other stuff.
CodePudding user response:
I ended up just doing this:
const changeTitle = () => {
if (this.state.saved === 'Show saved') {
this.setState({ saved: 'Hide saved' })
} else {
this.setState({ saved: 'Show saved' })
}