@ice/store v1.0.0-beta-3
English | 简体中文
icestore
Lightweight React state management library based on react hooks
Installation
icestore requires React 16.8.0 or later.
npm install @ice/store --saveIntroduction
icestore is a lightweight React state management library based on hooks. It has the following core features:
- Minimal & Familiar API: No additional learning costs, easy to get started with the knowledge of React Hooks.
- Class Component Support: Make old projects enjoying the fun of lightweight state management with friendly compatibility strategy.
- Built in Async Status: Records loading and error status of async actions, simplifying the rendering logic in the view layer.
- TypeScript Support: Provide complete type definitions to support intelliSense in VS Code.
Getting Started
Let's build a simple todo app from scatch using icestore which includes following steps:
Step 1 - Use a model to define your store:
export const todos = {
state: {
dataSource: [],
},
actions: {
async fetch(prevState, actions) {
await delay(1000);
const dataSource = [
{ name: 'react' },
{ name: 'vue', done: true},
{ name: 'angular' },
];
return {
...prevState,
dataSource,
}
},
add(prevState, todo) {
return {
...prevState,
dataSource: [
...prevState.dataSource,
todo,
]
};
},
},
};Step 2 - Create the store
import { createStore } from '@ice/store';
import * as models from './models';
export default createStore(models);Step 3 - Wrap your application
import React from 'react';
import ReactDOM from 'react-dom';
import store from './store';
const { Provider } = store;
ReactDOM.render(
<Provider>
<App />
</Provider>,
rootEl
); Step 4 - Consume model
import React, { useEffect } from 'react';
import store from './store';
const { useModel } = store;
function Todos() {
const [ state, actions ] = useModel('todos');
const { dataSource } = state;
const { fetch, add } = actions;
useEffect(() => {
fetch();
}, []);
function handleAdd(name) {
add({ name });
}
return (
<div>
<ul>
{dataSource.map(({ name, done }, index) => (
<li key={index}>
<label>
<input
type="checkbox"
checked={done}
onClick={() => onCheck(index)}
/>
{done ? <s>{name}</s> : <span>{name}</span>}
</label>
<button onClick={() => onRemove(index)}>-</button>
</li>
))}
</ul>
<div>
<input
onKeyDown={event => {
if (event.keyCode === 13) {
handleAdd(event.target.value);
event.target.value = '';
}
}}
placeholder="Press Enter"
/>
</div>
</div>
);
}API
createStore
createStore(models)
The function called to create a store.
import { createStore } from '@ice/store';
const store = createStore(models);
const { Provider, useModel, withModel } = store;Parameters
models
import { createStore } from '@ice/store'
const counterModel = {
state: {
value: 0
},
};
const models = {
counter: counterModel
};
createStore(models)state
state: any: Required
The initial state of the model.
const example = {
state: { loading: false },
};actions
actions: { [string]: (prevState, payload, actions, globalActions) => any }
An object of functions that change the model's state. These functions take the model's previous state and a payload, and return the model's next state.
const counter = {
actions: {
add: (prevState, payload) => prevState + payload,
}
};Actions provide a simple way of handling async actions when used with async/await:
const counter = {
actions: {
async addAsync(prevState, payload) => {
await delay(1000);
return prevState + payload;
},
}
};You can call another action by useing actions or globalActions:
const user = {
state: {
foo: [],
}
actions: {
like(prevState, payload, actions, globalActions) => {
actions.foo(payload); // call user's actions
globalActions.user.foo(payload); // call actions of another model
// do something...
return {
...prevState,
};
},
foo(prevState, id) {
// do something...
return {
...prevState,
};
},
}
};Return
Provider
Provider(props: { children, initialStates })
Exposes the store to your React application, so that your components will be able to consume and interact with the store via the hooks.
import React from 'react';
import ReactDOM from 'react-dom';
import { createStore } from '@ice/store';
const { Provider } = createStore(models);
ReactDOM.render(
<Provider>
<App />
</Provider>,
rootEl
); useModel
useModel(name: string): [ state, actions ]
A hook granting your components access to the model instance.
const counter = {
state: {
value: 0
},
actions: {
add: (prevState, payload) => ({...prevState, value: prevState.value + payload}),
}
};
const { userModel } = createStore({ counter });
functio FunctionComponent() {
const [ state, actions ] = userModel('name');
state.value; // 0
actions.add(1); // state.value === 1
}useModelActions
useModelActions(name: string): actions
A hook granting your components access to the model actions.
functio FunctionComponent() {
const actions = useModelActions('name');
actions.add(1);
}useModelActionsState
useModelActionsState(name: string): { [actionName: string]: { isLoading: boolean, error: Error } }
A hook granting your components access to the action state of the model.
functio FunctionComponent() {
const actions = useModelActions('name');
const actionsState = useModelActionsState('name');
useEffect(() => {
actions.fetch();
}, []);
actionsState.fetch.isLoading;
actionsState.fetch.error;
}withModel
withModel(name: string, mapModelToProps?: (model: [state, actions]) => Object = (model) => ({ [name]: model }) ): (React.Component) => React.Component
Use withmodel to connect the model and class component:
class TodoList extends Component {
render() {
const { counter } = this.props;
const [ state, actions ] = counter;
const { dataSource } = state;
state.value; // 0
actions.add(1);
}
}
export default withModel('counter')(TodoList);Browser Compatibility
![]() | ![]() | ![]() | ![]() | ![]() | ![]() | ![]() |
|---|---|---|---|---|---|---|
| ✔ | ✔ | ✔ | 9+ ✔ | ✔ | ✔ | ✔ |
Inspiration
icestore refines and builds upon the ideas of constate & rematch.
Contributors
Feel free to report any questions as an issue, we'd love to have your helping hand on icestore.
If you're interested in icestore, see CONTRIBUTING.md for more information to learn how to get started.
License
3 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago






