1 | # mini-store
|
2 |
|
3 | [![Travis](https://img.shields.io/travis/yesmeck/mini-store.svg?style=flat-square)](https://travis-ci.org/yesmeck/mini-store)
|
4 |
|
5 | A state store for React component.
|
6 |
|
7 | ## Motivation
|
8 |
|
9 | When you want to share a component's state to another one, a commom pattern in React world is [lifting state up](https://reactjs.org/docs/lifting-state-up.html#lifting-state-up). But one problem of this pattern is performance, assume we have a component in following hierarchy:
|
10 |
|
11 | ```javascript
|
12 | <Parent>
|
13 | <ChildA />
|
14 | <ChildB />
|
15 | <ChildC />
|
16 | </Parent>
|
17 | ```
|
18 |
|
19 | `ChildA` want to share state with `ChildB`, so you lifting `ChildA`'s state up to `Parent`. Now, when `ChildA`'s state changes, the whole `Parent` will rerender, includes `ChildC` which should not happen.
|
20 |
|
21 | Redux do a good job at this situation throgh keeping all state in store, then component can subscribe state's changes, and only connected components will rerender. But `redux` + `react-redux` is overkill when you are writing a component library. So I wrote this little library, It's like Redux's store without "reducer" and "dispatch".
|
22 |
|
23 | ## Example
|
24 |
|
25 | [See this demo online.](https://codesandbox.io/s/mq6223x08p)
|
26 |
|
27 | ```javascript
|
28 | import { Provider, create, connect } from 'mini-store';
|
29 |
|
30 | class Counter extends React.Component {
|
31 | constructor(props) {
|
32 | super(props);
|
33 |
|
34 | this.store = create({
|
35 | count: 0,
|
36 | });
|
37 | }
|
38 |
|
39 | render() {
|
40 | return (
|
41 | <Provider store={this.store}>
|
42 | <div>
|
43 | <Buttons />
|
44 | <Result />
|
45 | </div>
|
46 | </Provider>
|
47 | )
|
48 | }
|
49 | }
|
50 |
|
51 | @connect()
|
52 | class Buttons extends React.Component {
|
53 | handleClick = (step) => () => {
|
54 | const { store } = this.props;
|
55 | const { count } = store.getState();
|
56 | store.setState({ count: count + step });
|
57 | }
|
58 |
|
59 | render() {
|
60 | return (
|
61 | <div>
|
62 | <button onClick={this.handleClick(1)}>+</button>
|
63 | <button onClick={this.handleClick(-1)}>-</button>
|
64 | </div>
|
65 | );
|
66 | }
|
67 | }
|
68 |
|
69 | @connect((state) => ({ count: state.count }))
|
70 | class Result extends React.Component {
|
71 | render() {
|
72 | return (
|
73 | <div>{this.props.count}</div>
|
74 | );
|
75 | };
|
76 | }
|
77 | ```
|
78 |
|
79 | ## API
|
80 |
|
81 | ### `create(initialState)`
|
82 |
|
83 | Creates a store that holds the state. `initialState` is plain object.
|
84 |
|
85 | ### `<Provider store>`
|
86 |
|
87 | Makes the store available to the connect() calls in the component hierarchy below.
|
88 |
|
89 | ### `connect(mapStateToProps)`
|
90 |
|
91 | Connects a React component to the store. It works like Redux's `connect`, but only accept `mapStateToProps`. The connected component also receive `store` as a prop, you can call `setState` directly on store.
|
92 |
|
93 | ## License
|
94 |
|
95 | MIT
|