Redux 的简化版本 unistore

1,451 阅读2分钟
原文链接: github.com

unistore
npm travis

A tiny 650b centralized state container with component bindings for Preact.

  • Small footprint compliments Preact nicely
  • Familiar names and ideas from Redux-like libraries
  • Useful data selectors to extract properties from state
  • Portable actions can be moved into a common place and imported
  • Functional actions are just reducers

Table of Contents

Install

This project uses node and npm. Go check them out if you don't have them locally installed.

npm install --save unistore

Then with a module bundler like webpack or rollup, use as you would anything else:

// using ES6 modules
import { createStore, Provider, connect } from 'unistore'

// using CommonJS modules
const unistore = require('unistore')

The UMD build is also available on unpkg:

<script src="//unpkg.com/unistore/dist/unistore.umd.js"></script>

You can find the library on window.unistore.

Usage

import { Provider, createStore, connect } from 'unistore'

let store = createStore({ count: 0 })

// If actions is a function, it gets passed the store:
let actions = store => ({
	// Actions can just return a state update:
	increment(state) {
		return { count: state.count+1 }
	},

	// The above example as an Arrow Function:
	increment2: ({ count }) => ({ count: count+1 }),

	// Async actions can be pure async/promise functions:
	async getStuff(state) {
		let res = await fetch('/foo.json')
		return { stuff: await res.json() }
	},

	// ... or just actions that call store.setState() later:
	incrementAsync(state) {
		setTimeout( () => {
			store.setState({ count: state.count+1 })
		}, 100)
	}
})

const App = connect('count', actions)(
	({ count, increment }) => (
		<div>
			<p>Count: {count}</p>
			<button onClick={increment}>Increment</button>
		</div>
	)
)

export default () => (
	<Provider store={store}>
		<App />
	</Provider>
)

Examples

README Example on CodeSandbox

API

createStore

Creates a new store, which is a tiny evented state container.

Parameters

  • state Object Optional initial state (optional, default {})

Examples

let store = createStore();
   store.subscribe( state => console.log(state) );
   store.setState({ a: 'b' });   // logs { a: 'b' }
   store.setState({ c: 'd' });   // logs { a: 'b', c: 'd' }

Returns store

store

An observable state container, returned from createStore

setState

Apply a partial state object to the current state, invoking registered listeners.

Parameters

  • update Object An object with properties to be merged into state
  • overwrite Boolean If true, update will replace state instead of being merged into it (optional, default false)
subscribe

Register a listener function to be called whenever state is changed.

Parameters

unsubscribe

Remove a previously-registered listener function.

Parameters

getState

Retrieve the current state object.

Returns Object state

connect

Wire a component up to the store. Passes state as props, re-renders on change.

Parameters

  • mapStateToProps (Function | Array | String) A function mapping of store state to prop values, or an array/CSV of properties to map.
  • actions (Function | Object)? Action functions (pure state mappings), or a factory returning them.

Examples

const Foo = connect('foo,bar')( ({ foo, bar }) => <div /> )

Returns Component ConnectedComponent

Provider

Extends Component

Provider exposes a store (passed as props.store) into context.

Generally, an entire application is wrapped in a single <Provider> at the root.

Parameters

  • props Object
    • props.store Store A {Store} instance to expose via context.

Reporting Issues

Found a problem? Want a new feature? First of all see if your issue or idea has already been reported. If don't, just open a new clear and descriptive issue.

License

MIT License © Jason Miller