

GitHub - alexfoxy/juicr.js: A simple (and tiny ~1kb) redux inspired reducer for...
source link: https://github.com/alexfoxy/juicr.js
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

README.md
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, or even vanilla JS template literals.
Why?
I liked the redux pattern but the amount of boiler plate seemed overkill, especially for smaller projects.
Examples
All examples use the same juicr reducer code.
Setup
Add the package to your project either with:
# npm npm install juicr.js # yarn yarn add juicr.js
or for browsers:
<script src="https://cdn.jsdelivr.net/npm/juicr.js" ></script>
Simple example
- Create a new Juicr with some initial state:
const juicr = new Juicr({ 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("*", (changedState, _state) => { document.body.innerHTML = changedState.count /* or your front end library update function e.g. this.setState({ ...changedState }) */ })
- Dispatch actions to the Juicr:
setInterval(() => { juicr.dispatch("count", 1) }, 1000)
Play with this example in CodePen.
For use with React see: Use with React & React Native
API
new Juicr({ initialState={}, dev=false })
Initializes a new Juicr. Pass in an initialState
object and an optional dev
flag. When dev mode is enabled all changes to the state are printed to the console.
juicr.action('actionName', (data, _state) => { })
Adds a dispatchable action to the Juicr. Specify the actionName
and a function
that returns the state changes. The data
is passed in from the dispatch call as well as the current Juicr _state
. For example:
juicr.action('delete', ({ id }, _state) => { return { items: _state.items.filter(t => t.id !== id ) } })
juicr.dispatch('actionName', data)
Dispatches an action with data
on your Juicr. For example:
juicr.dispatch("delete", { id: 1 })
juicr.listen('propName', (changedState, _state) => { })
Listens to changes to the state 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) => {})
juicr.reaction('propName', (changedState, _state) => { })
Reacts to changes in the state and returns new state changes, essentially like a computed property. Similar to listen 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 } })
Asynchronous actions
Actions can return a Promise
which resolves with the state changes. When dispatching use .then
for triggering other actions or .catch
for errors. Eg.
juicr.action("setText", (text) => { return new Promise((resolve) => { setTimeout(() => { resolve({ text }) }, 100) }) }) juicr.dispatch("setLoading", true) juicr.dispatch("setText", "hello").then((changedState) => { juicr.dispatch("setLoading", false) // changedState.text === "hello" })
Multiple Juicrs
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.
Use with React & React Native
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 use setState
to update your state:
// App.js constructor() { ... this.juicr.listen("*", (changedState, _state) => { this.setState({ ...changedState }) }) ... }
Then pass the juicr.dispatch
function to components:
<MyComponent dispatch={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.js constructor(props) { ... this.state = { username: '', photoUrl: '' } props.userJuicr.listen(["username", "photoUrl", (changedState, _state) => { this.setState({ ...changedState }) }) ... }
Recommend
-
20
README.md
-
44
with-rematch A HoC that implement reducer a la Rematch Inpired By Rematch.js ♡ Instalation npm install -g with-rematch or yarn add with-rematch Getting St...
-
31
React with/without Redux Using a Global Reducer in React
-
36
Redux is an amazing tool if you take the time to get to know it. One of the things about Redux that commonly trips people up...
-
6
A simple program reducer for any language · CombyI’ve been fuzzing compilers for less familiar languages like Solidity and Diem (for smart contracts...
-
11
Introduction Have you ever had to reset your Redux state to its initial state in your reducers? Resetting the state is something lots of apps need to do. A typical example of when the app state must be reset could be when the user l...
-
3
什么是 redux? 三大原则? 什么是 redux Redux 是一个基于 js 的全局可预测状态容器,主要用于现代前端框架中进行全局状态管理,能够在不同组件之间进行状态共享 Redux 常与 React 配合使用,但它并非只能用于 React,由...
-
6
@rzhelieznovRomanJavascript and React fan. Also love reading, traveling, pc gaming :)
-
7
Frank Force 🌻 on Twitter: "Kiss Me Redux 💋 inspired by @revdancatt https://t.co/PNxLhEPvgv #generativeart #fxhash #javascript r=_=>Math.random()*900 X=510+r(Y=90+r(A=r(i=!t*2)|0)) with(x)for(fillStyle='#'+A;i--;(fill( arc(X+C(A+=22)*R,Y+S(A...
-
2
Closed Bug 1822293...
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK