Enables React apps to use @watchable/store for state-management
Read the API Reference or the reference usages below, or browse the source on Github.
// given some example store
interface CounterState {
counter: number;
active: boolean;
}
const counterStore = createStore<CounterState>({ counter: 0, active: false });
// bind Display to just the `counter` property
// won't re-render when `active` property changes
export const Display = (props: { store: Store<CounterState> }) => {
const counter = useSelected(props.store, (state) => state.counter);
return <h1>Counter is {counter}</h1>;
};
npm install @watchable/store-react
// create a store for the lifetime of this component
const store = useStore<CounterState>({ counter: 0, active: false });
A Store created through useStore
can be passed through prop
drilling or
Context to descendant components,
who will subscribe to the parts they want to track.
Note, using the useStore
hook can often be avoided. A Store can be a
singleton in most apps meaning
a single instance can simply be created and exported from a module.
If you are certain that an ancestor React component will never be replaced and
(hence) lose its state, then useStore
can be used safely.
If you want different parts of the render tree to have their own independent copy of some Store, it offers the convenience of components simply creating their own Stores inline.
const rootState = useRootState(props.store);
Note, this is rarely needed in production code for several reasons...
followSelector(...)
from @watchable/store-follow// Re-runs this functional component when any state changes
export const StateLog = (props: { store: Store<CounterState> }) => {
const rootState = useRootState(props.store);
const [stateHistory, setStateHistory] = useState<CounterState[]>([]);
useEffect(() => {
setStateHistory([...stateHistory, rootState]);
}, [rootState]);
return <h1>Counter is {counter}</h1>;
};
Our Example Counter Apps offer minimal demonstrations of @watchable/store