Maison >interface Web >js tutoriel >Partage de l'état entre des composants React non liés

Partage de l'état entre des composants React non liés

WBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWB
WBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBoriginal
2024-07-17 06:51:301184parcourir

Vous souhaitez montrer comment vous pouvez partager des données sérialisables entre des composants React, par ex. composants clients dans NextJS.

Nous avons quelques composants non liés :

Example app UI

Créons un objet qui contiendra l'état initial

export const state: { count: number } = { count: 0 };

On peut stocker des données dans une Map ou une WeakMap, l'état sera une clé pour y accéder. Il faudra également un tableau d’abonnés.

const stateMap = new WeakMap<object, object>();
const subscribers: (() => void)[] = [];

Écrivons maintenant un hook pour vous abonner aux modifications de données.

export function useCommonState<T extends object>(stateObj: T) {
  // more efficient than `useEffect` since we don't have any deps
  React.useInsertionEffect(() => {
    const cb = () => {
      const val = stateMap.get(stateObj);
      _setState(val!);
    };
    // subscribe to events
    subscribers.push(cb);

    return () => {
      subscribers.slice(subscribers.indexOf(cb), 1);
    };
  }, []);
}

Ajoutons maintenant la logique liée à l'obtention et à la définition de l'état

  // all instances of hook will point to same object reference
  const [state, _setState] = React.useState<typeof stateObj>(() => {
    const val = stateMap.get(stateObj) as T;
    if (!val) {
      stateMap.set(stateObj, stateObj)
      return stateObj
    }
    return val
  });

  const setState = React.useCallback((newVal: object) => {
    // update value
    stateMap.set(stateObj, newVal);
    // notify all other hook instances
    subscribers.forEach((sub) => sub());
  }, []);

  return { state, setState };

Et maintenant je peux l'utiliser en 3 composants comme

import { state as myState } from './state';
//...

const { state, setState } = useCommonState(myState);

<button
  onClick={() => setState({ count: state.count + 1 })}
  className="p-2 border"
>
  +
</button>
// ...
Component A<div>Count: {state.count}</div>

Final app

Vous pouvez voir comment cela fonctionne ici https://stackblitz.com/~/github.com/asmyshlyaev177/react-common-state-example
Ou ici https://codesandbox.io/p/github/asmyshlyaev177/react-common-state-example/main
Ou sur github https://github.com/asmyshlyaev177/react-common-state-example

Consultez ma bibliothèque pour NextJS basée sur ce principe https://github.com/asmyshlyaev177/state-in-url

Tnx pour la lecture.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn