helloitsjoe / react-hooks-compose

Decouple Hooks from the presentational components that use them

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Usage with zustand slice

KrisLau opened this issue · comments

commented

Thank you for this package! So zustand is a hook based state management library and they have a method to subscribe to only individual states within a store like this:

const nuts = useBearStore((state) => state.nuts)
const honey = useBearStore((state) => state.honey)

Which helps to avoid unnecessary re-renders.

I tried to use this method with react-hook-compose but I couldn't seem to get it working. What I've tried so far:

composeHooks({useBearStore((state) => state.nuts})
composeHooks({value: () => useBearStore((state) => state.nuts})

Any ideas as to what I could do to implement this?

Hello! I haven't used Zustand but I can investigate this. Do you have a minimal reproducible example, for example a CodeSandbox or StackBlitz link?

commented

Thanks for the quick reply! Made a simple Expo Snack with both zustand and react-hooks-compose for you: https://snack.expo.dev/@kris_lau/zustand-react-hooks-compose

Your second example seems to work for me, updated snack here: https://snack.expo.dev/TCRtl9VzM

export default composeHooks({ count: () => useStore((state) => state.count) })(App);

If I'm missing something, it would be great if you could update your example to show what's not working!

commented

So when I do it in my project I get the rule of hooks error:
image
and if I try to do multiple values, I get a prop already exists error:
image

In this case the linter can't infer that the hook will be used inside a Component, which is what's causing the rule of hooks error.

You should be able to resolve this in a couple of ways:

  1. You can ignore the rules of hooks warning with // eslint-disable-next-line react-hooks/rules-of-hooks
  2. If you prefer not to disable that eslint rule, you could create wrapper hooks. This will make the rules of hooks happy and will avoid the prop already exists error above:
export default composeHooks({
    useText: () => ({ text: useStore(state => state.text) }),
    useCount: () => ({ count: useStore(state => state.count) }),
})(Component);

I wasn't able to reproduce the prop already exists error, and I can't tell much from the screenshot. If that's still happening please send a link to a reproduction of the issue in a Snack, CodeSandbox, CodePen, StackBlitz etc. - somewhere where I can poke around the code.

Did that solve your issue? I'll close this issue if so, otherwise let me know and I'll look into it some more.

Closing, feel free to reopen if this is still unresolved!