State Basics
Overview
If props are the data passed down from a parent, State is the internal memory of the component itself.
Standard JavaScript variables do not work for UI rendering in React. If you create let count = 0; and attach a button that does count = count + 1, the variable will update in the computer's memory, but the React UI will completely ignore it. React only repaints the screen when it is explicitly told to do so.
State is React's mechanism for explicitly telling the Virtual DOM: 'My internal data has changed, please re-run this component and update the screen.' Whenever a state variable is updated, React triggers a Re-render of that specific component and all of its children, instantly reflecting the new data on the user's screen. State is the heart of React interactivity.
Syntax
function BrokenCounter() {
let count = 0; // Standard JS variable
const increment = () => {
count += 1;
console.log("Memory count:", count);
// This logs 1, 2, 3... but the UI NEVER updates!
};
return (
<div>
<h2>Count: {count}</h2>
<button onClick={increment}>Add</button>
</div>
);
}Common Pitfalls
- State is Asynchronous: State updates in React do not happen immediately on the next line of code. If you call
setCount(5)and immediatelyconsole.log(count)on the very next line, it will print the OLD value. React waits until the event handler finishes running, then batches the updates and triggers a re-render. - State is Private: State is completely isolated and private to the specific instance of the component. If you render
<Counter />twice on the screen, they each get their own completely independentcountvariable. Clicking one does not affect the other.
Interview Questions
Props are external data passed down from a parent component, and they are strictly read-only. State is internal memory managed entirely by the component itself, and it is mutable (via the state setter function). A component can change its own state, but it can never change its own props.
When a state setter function is called, React schedules an update. It re-executes the component function from top to bottom, generating a new Virtual DOM tree. It diffs this new tree against the old one, and surgically updates the real DOM with the new values.
Real-World Example
Toggling UI Elements: This pattern is ubiquitous in UI development. Modals, dropdown menus, mobile navigation drawers, and accordions all rely on a simple boolean state variable to determine whether they should be rendered to the DOM.
// We use state to track whether a UI element is visible or hidden
function Accordion() {
// isExpanded is our State variable
// setIsExpanded is the ONLY way we are allowed to change it
const [isExpanded, setIsExpanded] = useState(false);
return (
<div className="border rounded-md">
<button
className="w-full font-bold p-4 text-left bg-gray-100"
onClick={() => setIsExpanded(!isExpanded)}
>
Click to {isExpanded ? 'Collapse' : 'Expand'}
</button>
{/* Conditional Rendering based on State */}
{isExpanded && (
<div className="p-4">
This is the secret hidden content that appears when you click the button!
</div>
)}
</div>
);
}Check Your Knowledge
Test your understanding of State Basics with these quick questions.