- Notifications
You must be signed in to change notification settings - Fork3
A simple (and tiny <1kb) redux inspired reducer for handling state changes.
License
alexfoxy/juicr.js
Folders and files
| Name | Name | Last commit message | Last commit date | |
|---|---|---|---|---|
Repository files navigation
A simple (and tiny ~1kb) redux inspired reducer for handling state, actions, reactions etc. Works well with React.js & React Native but can be combined with any front end library.
I liked the redux pattern but the amount of boiler plate seemed overkill, especially for smaller projects.
All examples use the samejuicr code.
Add the package to your project either with:
# npmnpm install juicr.js# yarnyarn add juicr.js
or for browsers:
<scriptsrc="https://cdn.jsdelivr.net/npm/juicr.js">
- Create a new Juicr with some initial state:
constjuicr=newJuicr({initialState:{count:0}})
- Add an action with a name and a function that returns the changed state:
juicr.action("count",(amount,_state)=>{return{count:_state.count+=amount}})
- Listen to state changes. You can either listen to a single property, an array or use
*to listen to all changes:
juicr.listen("count",(changedState,_state)=>{console.log(changedState.count)})
- Dispatch actions to the Juicr:
setInterval(()=>{juicr.dispatch("count",1)},1000)
Play with this example inCodePen.
For use with React see #use-with-react--react-native
Initializes a new Juicr. Pass in aninitialState object and an optionaldev flag. When dev mode is enabled all changes to the state are printed to the console.
Adds a dispatchableaction to the Juicr. Specify theactionName and afunction that returns the state changes. Thedata is passed in from thedispatch call as well as the current Juicr_state. For example:
juicr.action('delete',({ id},_state)=>{return{items:_state.items.filter(t=>t.id!==id)}})
Dispatches anaction withdata on your Juicr. For example:
juicr.dispatch("delete",{id:1})
Listens to changes to thestate either from an action, or a reaction. You can either specify a single property:
juicr.listen("items",(changedState,_state)=>{})
An array of properties:
juicr.listen(["propA","propB"],(changedState,_state)=>{})
Or use the special character* to listen to any changes on the state:
juicr.listen("*",(changedState,_state)=>{})
Reacts to changes in the state and returns new state changes, essentially like a computed property. Similar tolisten you can react to changes on a single property, an array of properties, or any change using*.
juicr.reaction('count',({ count},_state)=>{return{countIsPositive:count>0}})
Actions can return aPromise which resolves with the state changes. When dispatching use.then for triggering other actions or.catch for errors. Eg.
juicr.action("setText",(text)=>{returnnewPromise((resolve)=>{setTimeout(()=>{resolve({ text})},100)})})juicr.dispatch("setLoading",true)juicr.dispatch("setText","hello").then((changedState)=>{juicr.dispatch("setLoading",false)// changedState.text === "hello"})
Larger projects may benefit from using multiple Juicrs for different parts of your application data. For example you might have one Juicr for the user state and another for a list of todos.
Using juicr.js with React.js & React Native is easy. The simplest approach is to listen to all changes* in your main app component and usesetState to update your state:
// App.jsconstructor(){...this.juicr.listen("*",(changedState,_state)=>{this.setState({ ...changedState})})...}
Then pass thejuicr.dispatch function to components:
<MyComponentdispatch={this.juicr.dispatch}/>
Alternatively you could pass the entire juicr to your components and let them handle their own internal state and listen for changes, e.g:
// UserHeader.jsconstructor(props){...this.state={username:'',photoUrl:''}props.userJuicr.listen(["username","photoUrl",(changedState,_state)=>{this.setState({ ...changedState})})...}
About
A simple (and tiny <1kb) redux inspired reducer for handling state changes.
Topics
Resources
License
Uh oh!
There was an error while loading.Please reload this page.
Stars
Watchers
Forks
Packages0
Uh oh!
There was an error while loading.Please reload this page.