Want to show how you can share any serializable data between React components, e.g. client components in NextJS.
We have few unrelated components:
Let's create a object that will contain initial state
export const state: { count: number } = { count: 0 };
We can store data in a Map or a WeakMap, state will be a key to access it. Also, will need a subscribers array.
const stateMap = new WeakMap
Now let's write a hook to subscribe to data changes.
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); }; }, []); }
Now let's add logic related to get and set state
// 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 };
And now can use it in 3 components like
import { state as myState } from './state'; //... const { state, setState } = useCommonState(myState); // ... Component ACount: {state.count}
You can see how it works here https://stackblitz.com/~/github.com/asmyshlyaev177/react-common-state-example
Or here https://codesandbox.io/p/github/asmyshlyaev177/react-common-state-example/main
Or in github https://github.com/asmyshlyaev177/react-common-state-example
Check out my library for NextJS based on this principle https://github.com/asmyshlyaev177/state-in-url
Tnx for reading.
Disclaimer: All resources provided are partly from the Internet. If there is any infringement of your copyright or other rights and interests, please explain the detailed reasons and provide proof of copyright or rights and interests and then send it to the email: [email protected] We will handle it for you as soon as possible.
Copyright© 2022 湘ICP备2022001581号-3