A tiny ~650b centralized state container with component bindings for Preact & React.
- Small footprint complements 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
- NEW: seamlessly run Unistore in a worker via Stockroom
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:
// The store:
import createStore from 'unistore'
// Preact integration
import { Provider, connect } from 'unistore/preact'
// React integration
import { Provider, connect } from 'unistore/react'
Alternatively, you can import the "full" build for each, which includes both createStore
and the integration for your library of choice:
import { createStore, Provider, connect } from 'unistore/full/preact'
The UMD build is also available on unpkg:
<!-- just unistore(): -->
<script src="https://unpkg.com/unistore/dist/unistore.umd.js"></script>
<!-- for preact -->
<script src="https://unpkg.com/unistore/full/preact.umd.js"></script>
<!-- for react -->
<script src="https://unpkg.com/unistore/full/react.umd.js"></script>
You can find the library on window.unistore
.
import createStore from 'unistore'
import { Provider, connect } from 'unistore/preact'
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 }),
//Actions receive current state as first parameter and any other params next
//check this function as <button onClick={incrementAndLog}>
incrementAndLog: ({ count }, event) => {
console.info(event)
return { 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>
)
Make sure to have Redux devtools extension previously installed.
import createStore from 'unistore'
import devtools from 'unistore/devtools'
let initialState = { count: 0 };
let store = process.env.NODE_ENV === 'production' ? createStore(initialState) : devtools(createStore(initialState));
// ...
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
An observable state container, returned from createStore
Create a bound copy of the given action function.
The bound returned function invokes action() and persists the result back to the store.
If the return value of action
is a Promise, the resolved value will be used as state.
Parameters
action
Function An action of the formaction(state, ...args) -> stateUpdate
Returns Function boundAction()
Apply a partial state object to the current state, invoking registered listeners.
Parameters
update
Object An object with properties to be merged into stateoverwrite
Boolean Iftrue
, update will replace state instead of being merged into it (optional, defaultfalse
)
Register a listener function to be called whenever state is changed. Returns an unsubscribe()
function.
Parameters
listener
Function A function to call when state changes. Gets passed the new state.
Returns Function unsubscribe()
Remove a previously-registered listener function.
Parameters
listener
Function The callback previously passed tosubscribe()
that should be removed.
Retrieve the current state object.
Returns Object state
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. Every action function gets current state as the first parameter and any other params next
Examples
const Foo = connect('foo,bar')( ({ foo, bar }) => <div /> )
const actions = { someAction }
const Foo = connect('foo,bar', actions)( ({ foo, bar, someAction }) => <div /> )
Returns Component ConnectedComponent
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
Objectprops.store
Store A {Store} instance to expose via context.
Found a problem? Want a new feature? First of all, see if your issue or idea has already been reported. If not, just open a new clear and descriptive issue.