Хотите показать, как можно обмениваться сериализуемыми данными между компонентами React, например клиентские компоненты в NextJS.
У нас мало несвязанных компонентов:
Давайте создадим объект, который будет содержать начальное состояние
export const state: { count: number } = { count: 0 };
Мы можем хранить данные на карте или WeakMap, состояние будет ключом для доступа к ним. Также понадобится массив подписчиков.
const stateMap = new WeakMap
Теперь давайте напишем хук для подписки на изменения данных.
export function useCommonState(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); }; }, []); }
Теперь давайте добавим логику, связанную с получением и установкой состояния
// all instances of hook will point to same object reference const [state, _setState] = React.useState(() => { 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 };
И теперь можно использовать его в трех компонентах, например
import { state as myState } from './state'; //... const { state, setState } = useCommonState(myState); // ... Component ACount: {state.count}
Вы можете увидеть, как это работает здесь https://stackblitz.com/~/github.com/asmyshlyaev177/react-common-state-example
Или здесь https://codesandbox.io/p/github/asmyshlyaev177/react-common-state-example/main
Или в github https://github.com/asmyshlyaev177/react-common-state-example
Посмотрите мою библиотеку для NextJS, основанную на этом принципе https://github.com/asmyshlyaev177/state-in-url
Спасибо за прочтение.
Отказ от ответственности: Все предоставленные ресурсы частично взяты из Интернета. В случае нарушения ваших авторских прав или других прав и интересов, пожалуйста, объясните подробные причины и предоставьте доказательства авторских прав или прав и интересов, а затем отправьте их по электронной почте: [email protected]. Мы сделаем это за вас как можно скорее.
Copyright© 2022 湘ICP备2022001581号-3