<div class="container"></div>
const {
createContext,
Dispatch,
SetStateAction,
useContext,
useEffect,
useRef,
useState, } = React;
type ValueType = {
dispatches: { [key: string]: Set<Dispatch<SetStateAction<{}>>> };
values: { [key: string]: number | undefined };
};
const context = createContext<ValueType>(undefined as never);
const Component = ({ name }: { name: string }) => {
console.log(name);
const [_, setValue] = useState<{}>();
const { values, dispatches } = useContext(context);
useEffect(() => {
if (dispatches[name]) dispatches[name].add(setValue);
else dispatches[name] = new Set([setValue]);
return () => {
dispatches[name].delete(setValue);
};
}, [name]);
return (
<div>
{name}:{values[name]}
</div>
);
};
const Page = () => {
console.log("Main");
const manager = useRef<ValueType>({ dispatches: {}, values: {} }).current;
const { dispatches, values } = manager;
return (
<>
<button
onClick={() => {
values["A"] = (values["A"] || 0) + 1;
dispatches["A"].forEach((v) => v({}));
}}
>
A
</button>
<button
onClick={() => {
values["B"] = (values["B"] || 0) + 1;
dispatches["B"].forEach((v) => v({}));
}}
>
B
</button>
<button
onClick={() => {
values["C"] = (values["C"] || 0) + 1;
dispatches["C"].forEach((v) => v({}));
}}
>
C
</button>
<context.Provider value={manager}>
<Component name="A" />
<Component name="B" />
<Component name="C" />
<Component name="A" />
<Component name="B" />
<Component name="C" />
</context.Provider>
</>
);
};
ReactDOM.render(<Page />, document.querySelector(".container"));
View Compiled
This Pen doesn't use any external CSS resources.