skip to Main Content

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


  1. Updating your state as it currently is defined would be done thus:

    // example for KeyMain2 - KeyChild1
    setVal((prevState) => ({ ...prevState, KeyMain2: { ...prevState.KeyMain2, KeyChild1: !prevState.KeyMain2.KeyChild1 } }))
    

    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.

    Login or Signup to reply.
  2. You updating the wrong element of the state:

    <button
        onClick={() => {
            setVal((prevState) => ({
                KeyMain: {
                  ...prevState.KeyMain,
                  KeyChild1: !prevState.KeyMain.KeyChild1,
                },
              }));
            }}
          >
    

    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

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search