- Inject external data to React hook component
- Support action to remove or update data
- Light weight
- TypeScript support
yarn add @mcsheffey/reactive-store
or
npm install @mcsheffey/reactive-store
import { Store } from '@mcsheffey/reactive-store';
const store = new Store();
//init data
store.create('count', 0);
- Using StoreInjector to make your store binding data with React component
import { StoreInjector } from '@mcsheffey/reactive-store';
const Component = () => {
return <div></div>;
};
export const App = StoreInjector(store, Component);
//or
export const App = StoreInjector(store, () => {
return <div></div>;
});
- Many store can be inject into one Component, and two or more Component can use the same store
export const App = StoreInjector([countStore, todoStore], () => {
return <div></div>;
});
- To update or remove data from store use can use store action. There are two kind of action update (update data) or remove (delete data) from store. Note: add new data to store will not trigger component rerender. This is good because data need to be declare at first time.
//this will not rerender component
store.create('blah', 'hmmm???');
//this two above will trigger component to rerender
store.update('count', count + 1);
store.remove('count');
For some reason you may don't want to recreate data that extract from store every rerender, this can be achieved by using useCallback hook:
import * as React from 'react';
import { StoreInjector, Store } from '@mcsheffey/reactive-store';
const store = new Store();
store.create('count', 0);
const Component = () => {
//Memo count 'state'
const countMemo = React.useCallback(() => {
return store.get('count');
}, []);
//Effect on memo
React.useEffect(()=>{
console.log("count change")
},[countMemo()])
return <p>{countMemo()}</p>;
};
export const App = StoreInjector(store, Component);
-
Middleware is a method provide by Store class, it allow you to control, debugging store behavior
-
Using middleware:
import {
DispatchAction,
Store,
StoreInjector,
} from '@mcsheffey/reactive-store';
export const store = new Store();
store.applyMiddleware(
(key: string, current: any, payload: any, type: DispatchAction) => {
console.log(key, current, payload, type);
}
);
store.create('count', 0);
for (let i = 0; i < 2; i++) {
const count = store.get('count');
store.update('count', count++);
}
store.delete('count');
/*
Log:
"count" 0 undefined "create"
"count" 0 1 "update"
"count" 1 2 "update"
"count" 2 undefined "delete"
*/
- key: the "key" of current data
- current: current value of data with "key"
- payload: a new value that use to update data with given key
- type: an action type (create,update or delete)
- You cant abort an action by return false in middleware function
store.applyMiddleware(
(key: string, current: any, payload: any, type: DispatchAction) => {
//abort action if count > 5
if (count > 5) {
return false;
}
}
);
store.create('count', 0);
for (let i = 0; i < 10; i++) {
const count = store.get('count');
store.update('count', count++);
}
import {
Store,
StoreInjector,
DispatchAction,
} from '@mcsheffey/reactive-store';
const store = new Store();
store.applyMiddleware(
(key: string, current: any, payload: any, type: DispatchAction) => {
console.log(key, current, payload, type);
if (count > 5) {
return false;
}
}
);
const keys = {
count: 'count',
};
/*Add data to store*/
store.create(keys.count, 0);
const Component = () => {
/*Get data from store */
const count: number = store.get(keys.count);
return (
<div className="App">
<button onClick={() => store.update(keys.count, count + 1)}>+</button>
</div>
);
};
const App = StoreInjector(store, Component);
const rootElement = document.getElementById('root');
ReactDOM.render(<App />, rootElement);
- See document for React version 18 here
- My inspiration to create this is from Michel Weststrate talk React Native Talks #1 - State Management Beyond the Libraries / Michel Weststrate
- If there are any issue or contribution please let me known :D
- Have good day!!!