~/
hackweb.dev
State with useState
Quiz
⌘K
...
~/
/tutorials
/react/react-state/edit
~ Contribute
Suggest a correction or improvement. The author reviews it before it goes live.
Loading...
Comment
0 / 300
Typo
Grammar
Broken link
Clarify
Code
en/tutorials/react/5react-state
Write
Preview
Diff
# State with useState State is data that changes over time within a component. The `useState` hook lets you add state to function components. ## Basic Syntax ```jsx import { useState } from "react"; function Counter() { const [count, setCount] = useState(0); return <p>Count: {count}</p>; } ``` `useState` returns an array: the current state value and a setter function. ## Updating State Call the setter to trigger a re-render: ```jsx function Counter() { const [count, setCount] = useState(0); return ( <div> <p>{count}</p> <button onClick={() => setCount(count + 1)}>+1</button> </div> ); } ``` React re-renders the component with the new value. ## State vs Variables A regular variable resets on every render: ```jsx function Bad() { let x = 0; x = x + 1; // Resets to 0 next render return <p>{x}</p>; } function Good() { const [x, setX] = useState(0); setX(x + 1); // Persists across renders return <p>{x}</p>; } ``` State persists. Variables don't. ## State is Asynchronous React batches state updates. The state variable doesn't update immediately: ```jsx function Demo() { const [count, setCount] = useState(0); function handleClick() { setCount(count + 1); console.log(count); // Still 0! } return <button onClick={handleClick}>{count}</button>; } ``` The `console.log` shows the old value because state updates are batched. ## Functional Updates When the new state depends on the previous state, use a function: ```jsx setCount(prev => prev + 1); setCount(prev => prev + 1); // Both work correctly — prev is always current ``` Without the function, both reads use the same stale `count`. ## Lazy Initialization Pass a function to `useState` for expensive initial computations: ```jsx const [data, setData] = useState(() => { return JSON.parse(localStorage.getItem("saved")); }); ``` The function only runs on the first render. ## Best Practices 1. **Use functional updates** — When new state depends on old state 2. **Keep state minimal** — Derive values instead of duplicating 3. **Use one state object** — For related values: `useState({ name, age })` 4. **Initialize with lazy values** — For expensive computations ## Common Mistakes 1. **Mutating state directly** — `state.value = x` won't trigger re-render 2. **Assuming state updates are synchronous** — They're batched and async 3. **Forgetting the setter** — `const [x] = useState(0)` — no way to update 4. **Overusing useState** — Combine related values into one state object
No changes yet
Reset to original
Submit suggestion
cancel