charkour / zundo

🍜 undo/redo middleware for zustand. <700 bytes
https://codesandbox.io/s/zundo-2dom9
MIT License
616 stars 20 forks source link

Uncaught TypeError: Cannot read properties of undefined (reading 'subscribe') #92

Closed vaynevayne closed 1 year ago

vaynevayne commented 1 year ago

How do I work with context?

i have a sample demo, but it not work, please help me look at ,thanks

https://stackblitz.com/edit/react-ts-fmst33?file=Child.tsx

or https://codesandbox.io/p/sandbox/react-vite-ts-9qputt

or https://stackblitz.com/edit/vitejs-vite-dsvpc4?file=src/store.tsx

vaynevayne commented 1 year ago

brother If has way to resolve it? @charkour

charkour commented 1 year ago

HI @vaynevayne,

Thank you for your message. Here is the zustand documentation for working with context. Does this answer your question?

Thanks

vaynevayne commented 1 year ago

It's been a long time Didn't you read the link again? What do you think is the inconsistency between my code and the context usage on its official website? @charkour You go in and have a look at the link, remove your zundo, the function is normal, plus you will report an error, can you be more serious?

charkour commented 1 year ago

Hi @vaynevayne,

I looked at the example, but found out that zustand v4 does not work with stackblitz. Can you please make a codesandbox with your code?

Thank you

vaynevayne commented 1 year ago

hello, @charkour this codesand :

https://codesandbox.io/p/sandbox/agitated-monad-khz4y4?file=%2Fsrc%2Fstore.tsx

vaynevayne commented 1 year ago

I'm sorry. I feel like I may have written the code wrong. can you correct it for me? @charkour

image
charkour commented 1 year ago

Thanks for the reproduction!

Does this solve your issue? I added two lines to get the store from context and check that it is not falsy.

export const useTemporalStore = <T extends unknown>(
  selector: (state: TemporalState<State & Actions>) => T,
  equality?: (a: T, b: T) => boolean
) => {
  const store = useContext(BearContext);
  if (!store) throw new Error("Missing BearContext.Provider in the tree");
  useStore(store.temporal, selector, equality);
};

Link to Code Sandbox

vaynevayne commented 1 year ago

Thank you. This works

Excuse me, can the partial function work as follows? State1.filter

// current
const useStoreA = create<StoreState>(
  temporal(
    set => ({ ... }),
    { partialize: (state) => {
      const { field1, field2, ...rest } = state
      return { field1, field2 }
    }}
  )
)

// new
const useStoreA = create<StoreState>(
  temporal(
    set => ({ ... }),
    { partialize: (state) => {
      const { field1, field2, ...rest } = state
      return { field1.filter(...), field2 } // here
    }}
  )
)
charkour commented 1 year ago

Hi @vaynevayne, to filter properties off of objects, you can delete the property from an object. This assumes that field1 is an object.

If field1 = { width: 100, name: "John" } and you'd like to remove width, you can write the following.

const useStoreA = create<StoreState>(
  temporal(
    set => ({ ... }),
    { partialize: (state) => {
      const { field1, field2, ...rest } = state
      delete field1['width']
      return { field1, field2 }
    }}
  )
)