/use-shared-state

React hook for sharing state or notifying event between components. Just like the widget controller in Flutter.

Primary LanguageTypeScriptMIT LicenseMIT

npm npm bundle size ci

🐙 React hook for sharing state between components, inspired by the InheritedWidget in Flutter.

yarn add @nekocode/use-shared-state

Why choose it?

  1. It's lightweight and includes just over 100 lines of source code, making it very suitable for use in component or library projects
  2. 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:

Edit useSharedState - example

Usage

1. Share state between components

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);

2. Notify event between components

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');
  // ...
};