Write a tiny store, createStore(initial), and a useStore(store, selector) hook on useSyncExternalStore
Write store.js with two named exports. createStore(initialState) returns { getState, setState, subscribe }. getState() returns the current state. setState(next) takes a new state or an updater function, (state) => next, and calls every listener after a change, but not when the new state is the same value by Object.is. subscribe(listener) adds a listener and returns a function that removes it.
useStore(store, selector) reads a store from a component with useSyncExternalStore. selector picks the part the component needs, like (state) => state.items.length, and defaults to the whole state. A component renders again only when its selected value changes, even when the store is changed by code outside React, and it subscribes once, not on every render. You can assume selectors return a part of the state or a plain value, never a new object.
const cartStore = createStore({ items: [], note: "" });
function CartBadge() {
const count = useStore(cartStore, (state) => state.items.length);
return <span>Cart: {count}</span>;
}
// Anywhere, even outside React:
cartStore.setState((state) => ({ ...state, items: [...state.items, "Chai"] }));
import { useSyncExternalStore } from "react";
export function createStore(initialState) {
let state = initialState;
return {
getState: () => state,
setState: (next) => {
state = next;
},
subscribe: (listener) => () => {},
};
}
export function useStore(store, selector = (state) => state) {
// Read the store, and render again when the selected part changes.
return selector(store.getState());
}
- getState and setState, with a value or an updater
- subscribe calls listeners after each change until it's undone
- setting the same value doesn't call the listeners
- useStore follows changes made outside React
- without a selector, components share the whole state
- a component renders only when its selected part changes
- subscribes once per component, and unsubscribes when it goes away
The answer
Write it yourself first. Then compare it with a reference solution and the checks it passes.
Checking your sign-in…