React useState Hook for Beginners: A Simple Guide
Learn the React useState hook for beginners with simple, line-by-line examples. Understand state, re-renders, and how to build your first interactive component.
Learn the React useState hook for beginners with simple, line-by-line examples. Understand state, re-renders, and how to build your first interactive component.
Searching for "react usestate hook for beginners"? Here is the short answer: useState is a built-in React function that lets a component remember a value and update the screen automatically when that value changes. This guide explains exactly how it works, with small, copy-pasteable examples you can run today, even if you have never used a React hook before.
In plain JavaScript, a normal variable forgets its value every time a function runs again. A React component is just a JavaScript function, and it re-runs every time something changes on the screen. So if you stored a number in a normal variable, it would reset to its starting value on every re-render. useState solves this problem. It gives your component a piece of memory, called state, that survives between re-renders and tells React to redraw the screen whenever that memory changes.
React components receive data two ways: props, which come from a parent component and never change inside the child, and state, which a component owns and controls itself. If you have not compared the two yet, our earlier guide covers the difference in detail before you continue here.
Not sure how state is different from props? Read our beginner comparison first.
Read: React Props vs State ExplainedBefore building anything, look at the single line of code you will write every time you use this hook:
import { useState } from "react";
const [count, setCount] = useState(0);Line 1 imports useState from the react package, so React knows you want to use it. Line 3 calls useState(0), which sets the starting value to 0. useState always returns an array with exactly two items: the current value (count) and a function to change it (setCount). The square brackets on the left are JavaScript array destructuring, a shorthand for pulling both items out in one line. You can name these two items anything you like, but the pattern "thing" and "setThing" is the common convention in React code.
Here is a complete, working component that uses useState to count button clicks:
import { useState } from "react";
function Counter() {
const [count, setCount] = useState(0);
function handleClick() {
setCount(count + 1);
}
return (
<div>
<p>You clicked {count} times</p>
<button onClick={handleClick}>Click me</button>
</div>
);
}
export default Counter;Line 4 creates the state, starting count at 0. Lines 6 to 8 define a function that runs when the button is clicked; it calls setCount with the new value, count + 1. Line 12 shows the current count inside the JSX, using curly braces to insert a JavaScript value into the markup. Line 13 attaches handleClick to the button's onClick event. Every time you click, setCount runs, React updates its memory of count, and the component re-renders with the new number on screen. You never edit the page directly; you just update state, and React handles the redraw.
Beginners sometimes try count = count + 1 instead of calling setCount. This will not work. Changing a state variable directly does not tell React to re-render, so the screen never updates. Always change state through its setter function, here setCount.
useState is also how you read what a user types into a form. This pattern is called a controlled input, because React state controls the input's value:
import { useState } from "react";
function NameForm() {
const [name, setName] = useState("");
function handleChange(event) {
setName(event.target.value);
}
return (
<div>
<input value={name} onChange={handleChange} />
<p>Hello, {name || "stranger"}!</p>
</div>
);
}
export default NameForm;Line 4 starts name as an empty string. Line 6 defines handleChange, which runs on every keystroke; event.target.value is the text currently inside the input box. Line 11 sets the input's value to the name state, and attaches handleChange to its onChange event. Line 12 greets the user with what they typed, falling back to "stranger" if name is still empty. Because the input's value always comes from state, React and the screen never disagree about what the box contains.
| Regular variable (let x = 0) | State (useState(0)) |
|---|---|
| Resets every time the component re-runs | Keeps its value between re-renders |
| Changing it does not update the screen | Changing it (via the setter) redraws the screen |
| Fine for values used only inside one function call | Needed for anything the user should see change |
Try building this yourself before checking the answer below: a button that shows or hides a paragraph of text. You will need a boolean state, true or false, and a setter that flips it.
import { useState } from "react";
function Toggle() {
const [isVisible, setIsVisible] = useState(false);
return (
<div>
<button onClick={() => setIsVisible(!isVisible)}>
{isVisible ? "Hide" : "Show"} details
</button>
{isVisible && <p>Here are the details you were looking for.</p>}
</div>
);
}
export default Toggle;Line 4 starts isVisible as false, so the details are hidden at first. Line 8 flips the value with !isVisible, which turns true into false and false into true. Line 9 changes the button label based on the current state. Line 11 uses the && operator: if isVisible is true, the paragraph after && is shown; if it is false, nothing is rendered. This is a very common pattern for showing and hiding content in React.
useState gives a function component a piece of memory called state. It returns the current value and a function to update it, and calling that function tells React to re-render the component with the new value on screen.
A normal variable resets every time the component function runs again, and changing it does not tell React to update the screen. State persists between re-renders and automatically triggers a redraw when you call its setter function.
Yes. You can call useState as many times as you need, once for each independent piece of state, such as const [name, setName] = useState('') and const [age, setAge] = useState(0) in the same component.
React batches state updates and re-renders shortly after you call the setter, not instantly inside the same line of code. If you log the state variable right after calling its setter, you will often still see the old value; the new value appears on the next render.
Props are values passed down from a parent component and cannot be changed by the child. State is owned by the component itself and can be updated with its setter function, which is what causes the component to re-render.
Want a team that already knows React inside and out to build your product?
Talk to FepiqOccasional, no-fluff notes on shipping modern software — startups, automation, Laravel, Shopify and more. No spam, unsubscribe anytime.
Keep reading
What is an index in SQL? A plain-English guide with copy-paste examples showing how indexes speed up queries and when you actually need one.
Learn JavaScript DOM manipulation for beginners: select elements, change text and styles, and handle clicks with simple, copy-paste code examples.
Let's build something
Book a free discovery call. We'll listen, ask sharp questions, and send you a proposal within 3 business days.