2

I have been trying to add a key to a state dynamically in zustand. I have tried multiple ways like

1.

const store = (set, get) => ({
  keyAttrib: {key1: "value1", key2: 2},
  update: (key, value) => {
    let newState = { ...get().keyAttrib, [key]: value };
    set(newState);
  }
})
  1.   const store = (set) => ({
        keyAttrib: { key1: "value1", key2: 2 },
        update: (key, value) => {
          set((state) => ({ keyAttrib: { ...state.keyAttrib, [key]: value } }));
        },
      });
    

but none of them seem to be working.

  • 1
    can you provide more code? the second example works perfectly fine for me. Is it possible that you are using this within a form? – m_wer Jul 12 '22 at 12:10
  • I am using this with onChange method on select component `const update = useStore((state) => state.update); const keyAttrib = useStore((state) => state.keyAttrib) const handleChange = (value, val1, val2) => { if (value !== " ") { update("key3", val1); update("key4", val2); } };` – Bharat keswani Jul 12 '22 at 12:59

1 Answers1

2

The second example you provided works perfectly fine for me:

 const useStore = create((set) => ({
    keyAttrib: {key1: "value1", key2: 2},
    update: (key, value) =>
    set((state) => ({
      keyAttrib: {
            ...state.keyAttrib,
            [key]: value,
        },
    })),
  }));

Here's the working codesandbox (please ignore any styling) where you can add/update key-value pairs, the dropdown will always update key3. If this is still not helping, please provide a minimal wokring example on codesandbox.

event.preventDefault() is needed to prevent the form from performing a page refresh which will reset your Zustand Store with its initial value.

m_wer
  • 1,038
  • 1
  • 11
  • 19
  • 1
    Thanks, it did worked, not sure why it wasn't working earlier. one more thing, it shows the previous state on console logging, I have slightly changed your code [codesandbox](https://codesandbox.io/s/zustand-forked-jg5ckc?file=/src/index.js) – Bharat keswani Jul 12 '22 at 16:19
  • 1
    Glad I could help! You are still logging the previous value as the component has not been updated at this time. Setting the value is async. You can add the useEffect hook and add the keyAttrib in its dependency array. This will always log when the keyAttrib changes. [sandbox](https://codesandbox.io/s/zustand-forked-l3tjky?file=/src/index.js) useEffect(() => { console.log(keyAttrib) },[keyAttrib]) – m_wer Jul 13 '22 at 05:34