statezero-react-hooks
v0.1.2
Published
React hooks for Statezero
Maintainers
Readme
statezero-react-hooks
React hooks for statezero.
Getting Started
Install from npm.
npm install react statezero statezero-react-hooks --savestatezero-react-hooks is packaged as both ESM and UMD bundles:
ES6 Module (Recommended)
import { useStatezero, useStatezeroPath } from "statezero-react-hooks";ES6 Module from Source
Import directly from unbundled source files for maximum flexibility:
// Note that the import path ends with '/src'
import { useStatezero, useStatezeroPath } from "statezero-react-hooks/src";This gives your bundler complete control over transpilation and tree-shaking.
Browser Global
<script src="./node_modules/statezero/dist/statezero.js"></script>
<script src="./node_modules/statezero-react-hooks/dist/statezero-react-hooks.js"></script>
<script>
const { useStatezero } = window.statezeroReactHooks;
</script>Usage
useStatezero(selector, isSync)
Subscribe to state changes matching the selector. Returns the current selected state value.
selector- Optional. A string path, array of paths, or selector function (see statezero selectors)isSync- Optional. If true, updates are synchronous; otherwise debounced (default: false)
import { useStatezero } from "statezero-react-hooks";
function Counter() {
const count = useStatezero("count");
return <div>Count: {count}</div>;
}
function UserProfile() {
const user = useStatezero((state) => state.user);
return <div>Hello, {user?.name}</div>;
}useStatezeroPath(path, isSync)
Subscribe to a specific path in state. Returns a [value, setValue] tuple similar to React's useState.
path- Required. A dot notation string path (e.g.,"count","user.name","deeply.nested.value"). UnlikeuseStatezero, this hook does not accept function or array selectors.isSync- Optional. If true, updates are synchronous; otherwise debounced (default: false)
import { useStatezeroPath } from "statezero-react-hooks";
function Counter() {
const [count, setCount] = useStatezeroPath("count");
return (
<div>
<span>Count: {count}</span>
<button onClick={() => setCount(count + 1)}>Increment</button>
</div>
);
}
function NestedValue() {
const [value, setValue] = useStatezeroPath("deeply.nested.value");
return (
<input value={value || ""} onChange={(e) => setValue(e.target.value)} />
);
}Sync Variants
By default, state change notifications are debounced to the next tick. Use the sync variants for immediate updates:
import { useStatezeroSync, useStatezeroPathSync } from "statezero-react-hooks";
const count = useStatezeroSync("count");
const [value, setValue] = useStatezeroPathSync("path.to.value");Selector Stability
When using function or array selectors, define them outside the component or memoize them to avoid resubscribing on every render:
// Good: selector defined outside component
const selectUser = (state) => state.user;
function UserProfile() {
const user = useStatezero(selectUser);
return <div>{user?.name}</div>;
}
// Good: memoized selector
function FilteredItems({ category }) {
const selector = useMemo(
() => (state) => state.items.filter((i) => i.category === category),
[category],
);
const items = useStatezero(selector);
return (
<ul>
{items.map((i) => (
<li key={i.id}>{i.name}</li>
))}
</ul>
);
}String path selectors (e.g., "user.name") don't have this issue since strings are primitives.
API Reference
| Hook | Arguments | Returns | Description |
| ---------------------- | ---------------------- | ----------------- | ------------------------------------------------- |
| useStatezero | (selector?, isSync?) | value | Subscribe to state, return selected value |
| useStatezeroSync | (selector?) | value | Synchronous version of useStatezero |
| useStatezeroPath | (path, isSync?) | [value, setter] | Subscribe to string path, return value and setter |
| useStatezeroPathSync | (path) | [value, setter] | Synchronous version of useStatezeroPath |
Developing
npm install
npm run build # Development build (UMD + ESM)
npm run format # Format code with prettier
npm run lint # ESLint with zero-warning policy
npm run test # Run tests with Jest
npm run test:watch # Run tests in watch mode
npm run size # Check bundle size limitsPublishing
npm version minor # or major/patch - updates package.json and creates git tag
git push && git push --tagsPushing the tag is the whole release. The Release workflow runs the checks,
cuts the GitHub release, and publishes to npm. npm publish is not run by
hand.
Nothing here holds an npm token. The workflow authenticates with a short-lived
credential minted from its own OIDC claim, against a trusted publisher
registered on npm that names this repository and
.github/workflows/release.yml. Renaming that file stops publishing until the
trusted publisher is updated to match. Publishing this way also attests
provenance, which is why no --provenance flag appears anywhere.
Related Projects
- statezero - The core state management library
