🐙 React hook for sharing state between components, inspired by the InheritedWidget in Flutter.
yarn add @nekocode/use-shared-state
Why choose it?
- It's lightweight and includes just over 100 lines of source code, making it very suitable for use in component or library projects
- Update components within a minimum range. For example, if we share a shared-state with components b and e, only these components will be updated when the shared-state updates
a
+-+-+
| | |
b c d
|
e
相关文章: use-shared-state 源码阅读
Live demo:
The simplest usage:
const CounterContext = React.createContext(new SharedState(0));
const ComponentA = () => {
const sharedState = React.useContext(CounterContext);
const [state, setState] = useSharedState(sharedState);
return (
<div>
<div>state: {state}</div>
<button onClick={() => setState(state + 1)}>increase</button>
</div>
);
};
const ComponentB = () => {
const sharedState = React.useContext(CounterContext);
const [state] = useSharedState(sharedState);
return <div>state: {state}</div>;
};
const App = () => {
return (
<CounterContext.Provider value={new SharedState(0)}>
<ComponentA />
<ComponentB />
</CounterContext.Provider>
);
};
Advanced usage:
const sharedSate = useMemo(() => new SharedState(0), []);
// Only retrieve the current state value, the component will never be updated
const [state] = useSharedState(sharedState, false);
// Update the component only when the current state value is greater than 1
const [state] = useSharedState(sharedState, (current, prev) => current > 1);
// Change the value of the shared state without updating hooked components
const [, setState] = useSharedState(sharedState);
setState(1, false);
// When the first parameter (shared state) is null, use 1 as the initial state value
const [state] = useSharedState(null, true, 1);
Use ChangeNotifier
, ValueNotifier
, and useListen
to notify another component to invoke some callbacks. Please note that, unlike useSharedState
, useListen
will not trigger the re-rendering of the hooked component:
const refetchNotifier = new ChangeNotifier();
const eventNotifier = new ValueNotifier<string | null>(null);
const ComponentA = () => {
// ...
useListen(refetchNotifier, () => refetch());
useListen(eventNotifier, (value) => {
if (value === 'setState') {
setState();
}
});
// ...
};
// In component B, call notifyListeners/setValue to notify A
const ComponentB = () => {
// ...
refetchNotifier.notifyListeners();
eventNotifier.setValue('setState');
// ...
};