él-staté
Type safe state management for React.
Features
- Type safe: every state & action can be typed.
- Distributed store: no
combineReducers
to create root reducer. You can select multiple stores in single component. Action can dispatch other actions that belong to different store. - Reducer-less, full of action. You dispatch action that manipulate the state it self.
- Lazy store initialization: stores will not be initialized until it used on component or action.
- Tree shakable: unneeded actions & stores will not be bundled.
Usage
Please see example.
Use StoreProvider
import React from 'react';
import ReactDOM from 'react-dom';
import { StoreProvider } from 'el-state';
import App from './App';
ReactDOM.render(
<StoreProvider>
<App />
</StoreProvider>,
document.getElementById('root')
);
Define a store & actions
import { createStore } from 'el-state';
type CounterState = {
counter: number;
};
export const counterStore = createStore<CounterState>('counter', { counter: 0 });
export const setCounter = createAction(counterStore, ({ mergeState }, counter: number) => mergeState({ counter }));
export const resetCounter = createAction(counterStore, ({ dispatch }) => dispatch(setCounter, 0));
export const increaseCounter = createAction(counterStore, ({ state }) => ({ ...state, counter: state.counter + 1 }));
Use the store
function MyComponent() {
const counter: number = useStore(counterStore, state => state.counter);
return <div>{counter}</div>;
}
Select multiple store
const useSelector = createSelector(getStore => {
const { counter } = getStore(counterStore);
const { name } = getStore(accountStore);
return counter > 1 ? name : '';
});
function MyComponent() {
const name = useSelector();
return <div>{name}</div>;
}
Call an action
function MyComponent() {
const onIncrease = useAction(increaseCounter);
<button onClick={onIncrease}>Increase</button>;
}
Or
function MyComponent() {
const dispatch = useDispatcher();
const onIncrease = () => dispatch(increaseCounter);
}
Create event handler
function MyComponent() {
const onChange = useActionCallback(setCounter, (e: React.ChangeEvent<HTMLInputElement>) => [
parseInt(e.target.value, 10),
]);
return <input value={counter} onChange={onChange} />;
}
Attribution
Nachos icon by Icons8