Skip to Content
useS v2.1.0 is released 🎉
DocsLocal State

Local State

🧩 How to Manage Local State?

useS is designed to replace useState and improve your local state management with minimal effort.

Component.tsx
import { useS } from "use-s-react"; export default function Component() { const [state, setState] = useS(false); return ( <button onClick={() => setState((prev) => !prev)}> {state ? "Es" : "En"} </button> ); }

😵 Too Many useState Calls?

It’s common to see components filled with multiple useState declarations:

ManyUseStates.tsx
import { useState } from "react"; export default function ManyUseStates() { const [count, setCount] = useState(0); const [show, setShow] = useState(true); const [score, setScore] = useState<number | undefined>(undefined); const [title, setTitle] = useState<string | null>(null); const [list, setList] = useState<number[]>([]); // and more return ... }

You could replace each useState with useS, but you’d still have a bloated list.


✅ One Object, One useS

Instead, consolidate all state into one object:

OnlyOneUseS.tsx
import { useS } from "use-s-react"; type InitialValue = { count: number; show: boolean; score: undefined | number; title: null | string; list: number[]; }; const initialValue: InitialValue = { count: 0, show: true, score: undefined, title: null, list: [], }; export default function OnlyOneUseS() { const [{ count, show, score, title, list }, setState] = useS(initialValue); return ( <div> <section> {count} <button onClick={() => setState(prev => ({ count: prev.count + 1}))}>+1</button> </section> <section> {show ? "Hello!" : "Bye!"} <button onClick={() => setState(prev => ({ show: !prev.show}))}>Hello | Bye</button> </section> <section> {score ? score : ""} <button onClick={() => setState({ score: 10 })}>Set 10</button> </section> <section> {title} <button onClick={() => setState({ title: "Hello useS" })}>Hello useS</button> </section> <section> <ul> {list.map((i) => ( <li key={'key-' + i}>number:{i}</li> ))} </ul> <button onClick={() => setState(prev => ({ list: [...prev.list, prev.list.length + 1]}))}>Add Item</button> </section> </div> ); }

ℹ️ Note: If you want to maintain the best performance in your application, always pass the same reference or initialValue to useS(). This is achieved by declaring initialValue outside the component and passing it to the hook.

Update only the pieces you need. For example:

setState({ score: 10 });

🧬 Updating Deeply Nested Object State

type User = { name: string; lastName: string; age: number; things: string[]; friend: { name: string; age: number; book: { title: string; pages: number; }; }; }; const user: User = { name: "John", lastName: "Doe", age: 29, things: ["t-shirt", "tv"], friend: { name: "Rose", age: 30, book: { title: "Game of JS", pages: 10, }, }, };

Update the nested friend.age:

setState({ friend: { age: 35 } });

Update book.title:

setState({ friend: { book: { title: "New Title" } } });

Or use a functional update:

setState((prev) => ({ age: prev.age + 1 }));

With useS, you don’t need to worry about deeply cloning or merging — it’s all handled automatically.

Last updated on