redux-zero-x
A lightweight state container inspired by redux-zero and make usage like mobx
Table of Contents
- Installation
- Usage
- Example
- Action
- Async
- Middleware
Installation
npm install redux-zero-x
Usage
use decorator
import {Provider, connect, Store, action} from 'redux-zero-x'
class CounterStore extends Store {
@action({throttle: 1000})
increment() {
return {count: this.getState().count + 1}
}
//no meta
@action
decrement() {
return {count: this.getState().count - 1}
}
// if set pure with false, the first argument is store's current state
@action({pure: false})
mul({count}, times) {
return {count: count * times}
}
}
const Counter = connect(['counterStore'])(({count, increment, decrement}) => (
<div>
<h1>{count}</h1>
<div>
<button onClick={decrement}>decrement</button>
<button onClick={increment}>increment</button>
</div>
</div>
))
const App = () => (
<Provider counterStore={new CounterStore({count: 0})}>
<Counter />
</Provider>
);
render(<App />, document.getElementById("root"));
use createStore
import {createStore} from 'redux-zero-x'
const counterStore = createStore({count:1}).actions(self => ({
increment() {
return {count: self.getState().count + 1}
}
decrement() {
return {count: self.getState().count - 1}
}
mul: {
meta: {pure: false},
value: ({count}, times) => ({count: count * times})
}
}))
Examples
in every example project's dirctory, run
npm install && npm run start
Action
In redux-zero-x, action is a function with some meta info and return update
@action(meta)
doSomething() {
// update is an object
return {foo:1}
}
or
@action(meta)
doSomething() {
// update is an function
return (state) => update
}
meta info
You can declare meta-info for action, and get it inmiddleware.
import { getMeta } from 'redux-zero-x'
let throttleMap = new Map()
function throttleMiddleware(action, next) {
const meta = getMeta(action)
const {throttle} = meta
if(!throttle) return next()
const now = Date.now()
if(!throttleMap.has(action) || now - throttleMap.get(action) >= throttle) {
throttleMap.set(action, now)
return next()
}
}
pure action
By default, every action is pure. You can use meta.pure = flase
to set action-function's first argument with current state, or use Store.defaultConfig.pure = false
to make all actions be pure.
Async
async function getUserInfo(userId) {
return fetch(`/user/${userId}`).then(resp => resp.json())
}
class myStore extends Store {
toggleLoading(loading) {
if(loading === undefined) {
loading = !this.getState().loading
}
this.setState({loading})
}
@action()
async fetchUser(id) {
this.toggleLoading()
const user = await getUserInfo(id)
this.toggleLoading()
return {user: user}
}
}
Middleware
import { getMeta } from 'redux-zero-x'
async function loggerMiddleware(action, next) {
const meta = getMeta(action)
console.group(`${meta.name}`)
await next()
console.groupEnd(`${meta.name}`)
}
async function delayMiddleware(action, next) {
await delay(100)
next()
}
// global middlewares
Store.use(loggerMiddleware, delayMiddleware)
// store middlewares
let store = new Store({count: 1}, loggerMiddleware, delayMiddleware)
Licence
MIT
注:本文内容来自互联网,旨在为开发者提供分享、交流的平台。如有涉及文章版权等事宜,请你联系站长进行处理。