React xStore
Simple yet powerful global state management for React, Inspired by Vuex, Redux and react-global-store, Support's Async mutations by (Actions), see examples for more informations.
Installation
npm install --save react-xstore
Usage
Wrap your components with Connect
and the store will be available as store
in props this.props.store.myStore
then you can access store api from any component you wrap with.
- access store
let mys = this.props.store.myStore
. - get current store state
mys.state.variable
. - call mutations
mys.commit('mutation', ...params)
. - call actions for async code
mys.dispatch('action', ...params)
. - manual state mutation
mys.setState({variable: 'hello'})
. - combine states or shrink object by computed property
mys.computed.variables
. - magic state getter
mys.variable
. - magically update state value by proxy
mys.variable = 'hello'
. - link store with your component, you can add stores as second parameter or leave it blank to init all stores to the component
Connect(Component, ['store1', 'store2'])
.
and you can access the stores externally by import {External as xStore} from 'react-xstore';
then fetch store like xStore.myStore
and now you have all internal methods and states available, you can commit, dispatch, setStore or update state magically.
Example 1 - simple counter
Init Store, you should import it at the main app loader
import {Store} from 'react-xstore';
new Store ({
name: 'myStore',
state: { // default state for current store
counter: 25,
},
mutations: { // called by commit() function
plus (append) {
this.counter = this.counter ? this.counter + append : 60;
},
},
actions: {
plusAsync (append) { // called by dispatch() function
setTimeout (() => {
this.commit ('plus', append);
}, 500);
},
},
computed: {
x5 () {
return this.counter * 5;
},
},
});
access store from any component like this
import React, {Component} from 'react';
import {Connect} from 'react-xstore';
class First extends Component {
render () {
const {state, computed, setState, commit, dispatch} = this.props.store.myStore;
return (
<div>
Counter is {state.counter} and x5 is {computed.x5}<br />
<button
onClick={() => {
setState ({
counter: state.counter ? state.counter + 1 : 1,
});
}}
>
setState +1
</button>
<button onClick={() => commit ('plus', 50)}>
Commit +50
</button>
<button onClick={() => dispatch ('plusAsync', 100)}>
Dispatch Async +100
</button>
</div>
);
}
}
export default Connect (First, ['myStore']); // access wanted stores only, for better performance
Example 2 - advance auth manager
Init Store, and import it at the main app loader
import {Store} from 'react-xstore';
const LOGIN = 'LOGIN';
const LOGIN_SUCCESS = 'LOGIN_SUCCESS';
const LOGOUT = 'LOGOUT';
new Store ({
name: 'auth',
state: {
isLoggedIn: !!localStorage.getItem ('token'),
},
mutations: {
[LOGIN] () {
this.pending = true;
},
[LOGIN_SUCCESS] () {
this.isLoggedIn = true;
this.pending = false;
},
[LOGOUT] () {
this.isLoggedIn = false;
},
},
actions: {
login (creds) {
this.commit (LOGIN);
return new Promise (resolve => {
setTimeout (() => {
localStorage.setItem ('token', 'JWT');
this.commit (LOGIN_SUCCESS);
resolve ();
}, 1000);
});
},
logout () {
localStorage.removeItem ('token');
this.commit (LOGOUT);
},
},
});
component example usage
import React, {Component} from 'react';
import {Connect} from 'react-xstore';
class Login extends Component {
render () {
const {state, dispatch} = this.props.store.auth;
return (
<div>
{state.isLoggedIn
? <span>Logged</span>
: <span>You Need to Login</span>}
{state.pending && <span>...</span>}
<br />
{!state.isLoggedIn &&
<button onClick={() => dispatch ('login', {user: 'name'})}>
Login
</button>}
{state.isLoggedIn &&
<button onClick={() => dispatch ('logout')}>
Logout
</button>}
</div>
);
}
}
export default Connect (Login); // access all stores
update store by magic setter
let auth = this.props.store.auth;
auth.username = 'Tamer Zorba';
Contributing
Thank you for considering contributing! Fork the repo then after you complete your awesome feature, make a pull request and we will be glad to accept after test.
License
This code is open-sourced software licensed under the MIT license