A lightweight state container inspired by redux-zero and make usage like mobx
TypeScript JavaScript
Switch branches/tags
Nothing to show
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Failed to load latest commit information.
.vscode test(all): add base test cases Dec 28, 2017
config test(all): add base test cases Dec 28, 2017
examples doc(readme): add more action's usage Jan 6, 2018
src doc(readme): add more action's usage Jan 6, 2018
.gitignore
.npmignore init Dec 26, 2017
LICENSE add licence Jan 4, 2018
README.md license Jan 25, 2018
package-lock.json feat(script): add deploy script Dec 26, 2017
package.json feat(config): add defaultConfig for store Jan 6, 2018
tsconfig.json test(all): add base test cases Dec 28, 2017
tslint.json
yarn.lock test(all): add base test cases Dec 28, 2017

README.md

redux-zero-x

A lightweight state container inspired by redux-zero and make usage like mobx

Table of Contents

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 in middleware.

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)

License

MIT