You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I like it! It'd be a little unfortunate to drop the action binding stuff though. Maybe something like this?
import{createContext}from'preact';import{useState,useContext,useMemo,useEffect}from'preact/hooks';constStoreContext=createContext(store);exportconstProvider=StoreContext.Provider;functionrunReducer(state,reducer){if(typeofreducer==='function')returnreducer(state);constout={};if(Array.isArray(reducer))for(letiofreducer)out[i]=state[i];elseif(reducer)for(letiinreducer)out[i]=state[reducer[i]];returnout;}functionbindActions(store,actions){if(typeofactions=='function')actions=actions(store);constbound={};for(letiinactions)bound[i]=store.action(actions[i]);returnbound;}exportfunctionuseStore(reducer,actions){const{ store }=useContext(StoreContext);const[state,set]=useState(runReducer(store.getState(),reducer));useEffect(()=>store.subscribe(state=>{set(runReducer(state,reducer));}));constboundActions=useMemo(bindActions,[store,actions]);return[state,boundActions];}
Another neat alternative would be to split the hooks into useStoreState() and useActions():
constACTIONS={add: ({ count })=>({count: count+1})};functionDemo(){const[count]=useStoreState(['count']);constadd=useActions(ACTIONS.add);// or to bind them all:const{ add }=useActions(ACTIONS);return<buttononclick={add}>{count}</button>}
Reacted by Joscha Rohmann, 伊撒尔, Dmitry Iv., pungggi, Jahred Hope, Tobias Bleckert, Brandon Istenes and Pablo Igarzábal
Reacted by Joscha Rohmann, thadeu, Dmitry Iv., Vlad Durnea and Pablo Igarzábal
That pattern would save some levels of nested components. @developit any plans on creating them? I'm right in the situation of refactoring App with hooks, that'd be a great help. I can come up with PR I guess.
I like it! It'd be a little unfortunate to drop the action binding stuff though. Maybe something like this?
import{createContext}from'preact';import{useState,useContext,useMemo,useEffect}from'preact/hooks';constStoreContext=createContext(store);exportconstProvider=StoreContext.Provider;functionrunReducer(state,reducer){if(typeofreducer==='function')returnreducer(state);constout={};if(Array.isArray(reducer))for(letiofreducer)out[i]=state[i];elseif(reducer)for(letiinreducer)out[i]=state[reducer[i]];returnout;}functionbindActions(store,actions){if(typeofactions=='function')actions=actions(store);constbound={};for(letiinactions)bound[i]=store.action(actions[i]);returnbound;}exportfunctionuseStore(reducer,actions){const{ store }=useContext(StoreContext);const[state,set]=useState(runReducer(store.getState(),reducer));useEffect(()=>store.subscribe(state=>{set(runReducer(state,reducer));}));constboundActions=useMemo(bindActions,[store,actions]);return[state,boundActions];}
I was playing around with this tonight and came up with #153
I still can't figure out why I have ONE test failing, but it retains all the previous APIs while also giving us a hook and nearly all previous tests passing. Heavily inspired by @thadeu to make something that will feel familiar to anyone who used the old API
Only downfall is that it will be a breaking change since it uses the new Context API
Pre React Hooks it was typical to use a single connect command for a component, with multiple selectors and multiple actions per connect.
I'm not sure this behaviour should carry over to hooks. Consumers can now use multiple hooks in a component. And this could be made possible by separating out selecting content from the store, useSelector, and creating an action, useAction.
With connect statement you might use something like:
Exactly @yuqianma . Aligning the API with Redux will help people moving between the frameworks.
The only difference is what consumers are passing to useAction.
Issues with the connect statement causing re-renders on irrelevant state changes, I think I need to work on the equality comparison.
useSelector doesn't accept an equality function. Wanted to get an MVP working first.
Though the big win for me is the TypeScript type inference.
State param's type is inferred in your actions:
And actions automatically have their parameters Types inferred:
@mihar-22 looks really good. The only change I'd like to see in your implementation is to allow passing selector values to useSelector() rather than just functions. You can import { select } from 'unistore/src/utils.js' or just copy it over.
Hey @mihar-22, I was following this thread and tried to use your proposal in my typical dashboard app that I'm porting from another framework.
Apparently, I don't see how useActions hook must be used with async functions. The bound value gets resolved to a listener only when the modified state is returned from hook function. Do you have any recommended usage pattern in mind?
Activity
[-]Hooks?[/-][+]useStore Hooks?[/+]thadeu commentedon Feb 1, 2019
example:
developit commentedon Mar 7, 2019
I like it! It'd be a little unfortunate to drop the action binding stuff though. Maybe something like this?
Usage:
developit commentedon Mar 7, 2019
Another neat alternative would be to split the hooks into
useStoreState()anduseActions():dy commentedon Apr 2, 2019
That pattern would save some levels of nested components. @developit any plans on creating them? I'm right in the situation of refactoring App with hooks, that'd be a great help. I can come up with PR I guess.
thadeu commentedon Apr 9, 2019
That pattern wouldn't support to preact 8.x right? so, we should be find solution for all versions, or something that work to separated versions.
@developit you have any ideia about it?
DonnieWest commentedon Apr 16, 2019
I was playing around with this tonight and came up with #153
I still can't figure out why I have ONE test failing, but it retains all the previous APIs while also giving us a hook and nearly all previous tests passing. Heavily inspired by @thadeu to make something that will feel familiar to anyone who used the old API
Only downfall is that it will be a breaking change since it uses the new Context API
Feedback welcome
jahredhope commentedon Jun 22, 2019
I'd like to add a suggestion about the API.
Pre React Hooks it was typical to use a single connect command for a component, with multiple selectors and multiple actions per connect.
I'm not sure this behaviour should carry over to hooks. Consumers can now use multiple hooks in a component. And this could be made possible by separating out selecting content from the store,
useSelector, and creating an action,useAction.With connect statement you might use something like:
With Hooks you'd be able to pull these out to seperate commands:
This potentially allows you to pull out common hooks such as
useSelectUserInfothat might be used in multiple places.yuqianma commentedon Jul 6, 2019
@jahredhope You would be interested in https://github.com/facebookincubator/redux-react-hook
jahredhope commentedon Jul 6, 2019
Exactly @yuqianma . Aligning the API with Redux will help people moving between the frameworks.
The only difference is what consumers are passing to
useAction.I had a crack at implementing it when I commented above, just a WIP:
https://gist.github.com/jahredhope/c0d490ec2c58aa45efd11d138b72d9ff
Though the big win for me is the TypeScript type inference.


State param's type is inferred in your actions:
And actions automatically have their parameters Types inferred:
Update:
Working on an implementation here:
https://github.com/developit/unistore/compare/master...jahredhope:add-hooks?expand=1
Which comes from a standalone implementation here:
https://github.com/jahredhope/react-unistore
I've just been testing the standalone implementation in some apps and seems to be working well.
dan-lee commentedon Aug 8, 2019
Would be lovely to get this in. I love this little library, but it's definitely missing support for hooks
mihar-22 commentedon Sep 26, 2019
I created some hooks for Unistore based heavily on react-redux and redux-zero.
Repo: https://github.com/mihar-22/preact-hooks-unistore
I'd love some feedback and maybe integrate it into Unistore?
developit commentedon Oct 17, 2019
@mihar-22 looks really good. The only change I'd like to see in your implementation is to allow passing selector values to
useSelector()rather than just functions. You canimport { select } from 'unistore/src/utils.js'or just copy it over.feat: selector can be a string or a function
mihar-22 commentedon Oct 18, 2019
All done @developit. I can keep it as a separate package or I can make a PR to pull it in and we can add it to
src/hooks? Either way no problemo.dkourilov commentedon Nov 12, 2019
Hey @mihar-22, I was following this thread and tried to use your proposal in my typical dashboard app that I'm porting from another framework.
Apparently, I don't see how
useActionshook must be used with async functions. The bound value gets resolved to a listener only when the modified state is returned from hook function. Do you have any recommended usage pattern in mind?mihar-22 commentedon Nov 12, 2019
Hey @dkourilov, if you can raise the issue over at https://github.com/mihar-22/preact-hooks-unistore then I can try and help when I have a moment. If you can provide a little bit more information that'd help, thanks :)
dan-lee commentedon Apr 30, 2020
Are there any plans to go forward with official unistore react/preact hooks?
khuyennguyen7007 commentedon May 21, 2020
Hope to see unistore and preact-hooks-unistore in a united package soon.
danielweck commentedon Jun 18, 2020
@developit ’s WIP gist: https://gist.github.com/developit/ecd64416d955874c3426d4582045533a
tomByrer commentedon Jul 19, 2020
Wouldn't install on Win10 for me :/