
Company News
Free Business Plan Upgrades for Open Source Maintainers
Open source maintainers are under more pressure than ever. We're raising our open source program from the Team plan to the Business plan, free.
@bhammond/react-stateful
Advanced tools
A Signal and Querystate backed React State management utility library.
Framework-agnostic URL-synchronized state management with built-in state sharing between components. Uses signals to share state efficiently between components.
npm install @bhammond/react-stateful
import { useQueryState } from '@bhammond/react-stateful';
function SearchComponent() {
const params = new URLSearchParams(window.location.search);
const [query, setQuery] = useQueryState('q', params);
return (
<input
value={query ?? ''}
onChange={(e) => setQuery(e.target.value)}
placeholder="Search..."
/>
);
}
Components using the same key will share state through signals:
import { useQueryState } from '@bhammond/react-stateful';
function SearchInput({ params }) {
const [query, setQuery] = useQueryState('q', params);
return <input value={query ?? ''} onChange={e => setQuery(e.target.value)} />;
}
function SearchResults({ params }) {
const [query] = useQueryState('q', params);
return <div>Results for: {query}</div>;
}
function FilterStatus({ params }) {
const [query] = useQueryState('q', params);
return <div>Current filter: {query || 'None'}</div>;
}
function SearchPage() {
const params = new URLSearchParams(window.location.search);
return (
<div>
<SearchInput params={params} />
<FilterStatus params={params} />
<SearchResults params={params} />
</div>
);
}
The hook works with complex objects and maintains type safety:
interface Filters {
search: string;
category: string;
sortBy: string;
page: number;
}
const DEFAULT_FILTERS: Filters = {
search: '',
category: 'all',
sortBy: 'date',
page: 1
};
function FilterPanel({ params }) {
const [filters, setFilters] = useQueryState<Filters>('filters', params, DEFAULT_FILTERS);
const updateFilter = (key: keyof Filters, value: Filters[keyof Filters]) => {
setFilters(current => ({
...current,
[key]: value,
page: key === 'page' ? value : 1
}));
};
return (
<div>
<input
value={filters.search}
onChange={e => updateFilter('search', e.target.value)}
/>
<select
value={filters.category}
onChange={e => updateFilter('category', e.target.value)}
>
{/* options */}
</select>
</div>
);
}
function useQueryState<T = string>(
name: string,
params: ParamsInput,
defaultValue?: T
): [T, (newValue: T | ((prev: T) => T)) => void]
name: string - URL parameter keyparams: ParamsInput - Either:
URLParamsLike: An object with a get(key: string): string | null methodRecordParams: An object with string or string array valuesdefaultValue?: T - Optional default value when parameter is not present[value, setValue] - A tuple containing the current value and setter functionimport { useSearchParams } from 'react-router-dom';
import { useQueryState } from '@bhammond/react-stateful';
function SearchComponent() {
const [searchParams] = useSearchParams();
const [query, setQuery] = useQueryState('q', searchParams);
return (
<input
value={query ?? ''}
onChange={(e) => setQuery(e.target.value)}
/>
);
}
class CustomParams implements URLParamsLike {
private params: Map<string, string>;
constructor() {
this.params = new Map();
}
get(key: string): string | null {
return this.params.get(key) ?? null;
}
set(key: string, value: string): void {
this.params.set(key, value);
}
}
function Component() {
const params = new CustomParams();
const [value, setValue] = useQueryState('key', params);
// ...
}
Includes TypeScript definitions with full type inference support.
Contributions are welcome. Please feel free to submit a Pull Request.
MIT
FAQs
A Signal and Querystate backed React State management utility library.
We found that @bhammond/react-stateful demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Company News
Open source maintainers are under more pressure than ever. We're raising our open source program from the Team plan to the Business plan, free.

Security News
The supply chain control that delays freshly published gems now covers lockfile generation and gem vendoring in Ruby projects.

Security News
During a UK cyber test, a Mythos 5 agent used sockpuppets, social engineering, and prompt injection to try to get a maintainer to merge malware.