@watchable/store-react
v1.0.2
Published
Update React components when @watchable/store state changes
Downloads
8
Maintainers
Readme
Store bindings for React
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.
Usage
Track a part of Store state
// 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>;
};
Getting Started
Install
npm install @watchable/store-react
Advanced
Create a store in a component
// 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.
Consume the whole state
const rootState = useRootState(props.store);
Note, this is rarely needed in production code for several reasons...
- well-architected business logic should live outside the render loop, using
followSelector(...)
from @watchable/store-follow - to consume part of the state, prefer {@link useSelector} which doesn't trigger renders on every state change
// 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>;
};
Demonstration Apps
Our Example Counter Apps offer minimal demonstrations of @watchable/store
- Counter Apps using various Web Frameworks:
- with React (using @watchable/store-react)
- with no framework (using @watchable/store-follow)
- with Preact (using @watchable/store-react) and aliased React
- Counter Apps using various Bundling approaches:
- via Commonjs
- via ESM
- for tiniest bundle (a tree-shaken counter app in just 406 bytes!)
- Counter Apps demonstrating Tips and Tricks:
- Manage Immutability using editable drafts - eliminates Immutable update patterns
- Share a store with multiple components using React Context API - eliminates prop drilling
- The fastest possible app using @watchable/store (32000 updates per second)
- The smallest possible app using @watchable/store-react (316 bytes)