I have a simple state with a key inside a key, and I want to change the value on click.
For example, I have this code:
const [Val, setVal] = useState({
KeyMain: { KeyChild1: true, KeyChild2: false }
});
And with this button I want to change the toggle
value in key KeyChild1
, and the second button in key KeyChild2
:
// KeyChild1
<button onClick={() => {
setVal((prevState) => ({ KeyMain: !prevState.KeyMain.KeyChild1 }));
}}
>
Click
</button>
// KeyChild2
<button onClick={() => {
setVal((prevState) => ({ KeyMain: !prevState.KeyMain.KeyChild2 }));
}}
>
Click
</button>
But that doesn’t change anything.
Can you please tell me where I went wrong?
EDIT
const [Val, setVal] = useState({
KeyMain1: { KeyChild1: true, KeyChild2: false }
KeyMain2: { KeyChild1: false, KeyChild2: true }
});
// FOR KeyMain1 --- KeyChild1
<button onClick={() => {
setVal((prevState) => ({ KeyMain1: { ...prevState.KeyMain1, KeyChild1: !prevState.KeyMain1.KeyChild1 } }))}
>
Click
</button>
// FOR KeyMain1 --- KeyChild2
<button onClick={() => {
setVal((prevState) => ({ KeyMain1: { ...prevState.KeyMain1, KeyChild2: !prevState.KeyMain1.KeyChild2 } }))}
>
Click
</button>
//////////////////////////////////////////
// FOR KeyMain2 --- KeyChild1
<button onClick={() => {
setVal((prevState) => ({ KeyMain2: { ...prevState.KeyMain2, KeyChild1: !prevState.KeyMain2.KeyChild1 } }))}
>
Click
</button>
// FOR KeyMain2 --- KeyChild2
<button onClick={() => {
setVal((prevState) => ({ KeyMain2: { ...prevState.KeyMain2, KeyChild2: !prevState.KeyMain1.KeyChild2 } }))}
>
Click
</button>
2
Answers
Updating your state as it currently is defined would be done thus:
You might want to consider using a different data structure for your state object that would make this easier (because currently the maintainability of this is subpar); or different states for KeyMain1 and KeyMain2; the useState hook can be used as often as you wish inside the same component.
A different data structure could be a special class you instantiate, which has update methods to toggle entries, which return a new instance of the class representing the new state.
You updating the wrong element of the state:
Working example:
https://stackblitz.com/edit/react-playground-practice-elxt6k?file=index.js%3AL33
But btw I think it’s better to keep the state simple, using a
useState
hook for each of the buttons instead of a complex object, as it can lead to performance issues