Skip to content

useProxyState

Hook to handle component state that allows you to use an object for your state and mutating it in a way more idiomatic for JS.

N.B.: not destructure state, otherwise break changes updated.

Demo

INFO

The component has:

  • a state created with useProxyStore, that is a object with num property, a number, and nested property that is a object with random property that is a string.
  • a useCallback function increment that increment num property.
  • a useCallback function random that generate random number, assigned to nested.random property.
  • a Child1 component that receives num and increment as props.
  • a Child2 component that receives nested.random and random as props.
Loading demo…
Show source code
tsx
import { memo, useCallback } from "react";
import { useProxyState } from "../../../..";

const Child1 = memo(({ state, onClick }: { state: number, onClick: ()=>void }) => {
	return (<>
		<p>Num value is: {state}</p>
		<button onClick={onClick} type={'button'}>Increment</button>
	</>);
});

const Child2 = memo(({ state, onClick }: { state: string, onClick: () => void }) => {
	return (<>
		<p>Random value is: {state}</p>
		<button onClick={onClick} type={'button'}>
			Change random
		</button>
	</>);
});

const UseProxyState = () => {
	const state = useProxyState({ num: 0, nested: { random: "" } }, true);
	const increment = useCallback(() => state.num++, [state.num]);
	const random = useCallback(() => state.nested.random = Math.random().toFixed(2), [state.nested]);
	return (
		<div>
			<p>
				Current Value (in the proxy state): {state.num}  -  random: {state.nested.random}
			</p>
			<Child1 state={state.num} onClick={increment}/>
			<Child2 state={state.nested.random} onClick={random} />
		</div>
	);
}

UseProxyState.displayName = "UseProxyState";

export { UseProxyState };

Types

UseProxyStateProps

  • @template T - The state object type. Must be a plain object (record).

Parameters accepted by useProxyState.

PropertyTypeRequiredDescription
initialStateT \| (() => T)The initial state object. Accepts either a direct value or a lazy initializer function invoked only on the first render.
proxyInDepthbooleanWhen true, nested objects within the state are also wrapped in a Proxy, making deep mutations reactive. When false (default), only top-level property assignments trigger a re-render.

UseProxyStateResult

  • @template T - The state object type.

Return value of useProxyState.

A Proxy-wrapped version of the state object T. Assigning any property directly on the returned object (e.g. state.count = 5) triggers a re-render automatically — no setter function is needed.

ts
export type UseProxyStateResult<T extends Record<string, any>> = T;

Released under the MIT License.