Introduction to React State
A masterclass tutorial covering What is State, State vs Props comparison matrix, useState hook syntax, Re-rendering trigger mechanics, State Initialization, Multiple state variables, Common Pitfalls, and Interview Questions.
What is State in React?
In React, State is a built-in JavaScript object used to store data or information about a component that can change over time.
Whenever a component's state changes, React automatically re-evaluates the component function and re-renders the user interface to reflect the new state in the DOM.
Analogy:
Think of a component's State like a digital scoreboard in a football match. When a team scores a goal, the scoreboard (state) changes, and the stadium screen (UI) instantly updates to display the new score.
State vs. Props โ The Core Comparison Matrix
Understanding the difference between State and Props is fundamental to mastering React:
| Feature | State | Props |
|---|---|---|
| Definition | Internal data managed *within* the component | External data passed *into* the component from parent |
| Mutability | Mutable (Can be updated via state setter function) | Immutable (Read-only, cannot be modified by child) |
| Ownership | Owned and controlled by the component itself | Owned and passed by the parent component |
| Triggers Re-render? | YES โ Calling setter function triggers re-render | YES โ Receiving new prop values triggers re-render |
| Initialization | Initialized inside component body (useState(0)) | Passed as HTML-like attributes (<Card name="iPhone" />) |
The useState Hook โ Syntax & Signature
React provides the useState hook function to declare state in functional components.
Import & Syntax:
import { useState } from 'react';
const [stateVariable, setStateFunction] = useState(initialValue);Breakdown of Array Destructuring:
stateVariable: Holds the current snapshot of the state value.setStateFunction: A function used to update the state variable and schedule a component re-render.initialValue: The starting value of the state when the component first mounts.
How State Updates Trigger Component Re-Renders
When you invoke a state setter function (e.g., setCount(5)), React performs 3 steps under the hood:
- State Update Queue: React schedules a state change with the new value.
- Component Function Execution: React re-runs (calls) your component function with the updated state value.
- Virtual DOM Diffing & DOM Reconciliation: React compares the newly generated Virtual DOM tree with the previous Virtual DOM tree and updates *only* the specific DOM nodes that changed in the real browser DOM!
Using Multiple State Variables vs Combined State
You can declare multiple independent state variables inside a single component:
function UserProfile() {
const [name, setName] = useState("Ravindra Nath Jha");
const [age, setAge] = useState(25);
const [isOnline, setIsOnline] = useState(true);
return (
<div>
<h2>{name} ({age} yrs)</h2>
<p>Status: {isOnline ? "Active ๐ข" : "Away ๐ด"}</p>
</div>
);
}Lazy State Initialization (Performance Optimization)
If calculating your initial state involves an expensive operation (e.g. reading from localStorage or parsing large JSON files), pass a callback function to useState:
// โ WRONG: Runs expensive function on EVERY render!
const [data, setData] = useState(getExpensiveData());
// โ
CORRECT: Runs callback ONLY once when component first mounts!
const [data, setData] = useState(() => getExpensiveData());Common Mistakes with Introduction to State
- Mutating State Directly: Writing
count = 5orstate.name = "John". React will NOT re-render the UI because setter functions were not called! - Calling
useStateinside loops or conditions: Hooks MUST always be called at the top level of your component function. - Reading State Immediately After Setting It: State updates are asynchronous; reading state on the very next line will log the *old* state value.
Top React Interview Questions on State
Q1: What is State in React and why do we need it?
*Answer*: State is a mutable data store managed inside a component. When state updates via setter functions, React automatically triggers a component re-render to reflect new data in the UI.
Q2: What is the difference between State and Props?
*Answer*: Props are immutable data passed down from a parent component, while State is mutable data created and managed locally within a component.
Q3: What happens if you mutate state directly without calling the setter function?
*Answer*: Direct mutations change the variable in memory, but React remains unaware of the change. Consequently, no re-render occurs, and the UI becomes out-of-sync.
Practical Hands-On Exercise โ Interactive Multi-State Counter & Toggle
Here is a complete interactive component managing numeric counters, step controls, and theme toggle states:
// Complete Masterclass State Introduction Showcase (src/App.jsx)
import React, { useState } from 'react';
export default function App() {
const [count, setCount] = useState(0);
const [step, setStep] = useState(1);
const [isDarkMode, setIsDarkMode] = useState(false);
return (
<div style={{
maxWidth: "500px",
margin: "30px auto",
padding: "24px",
background: isDarkMode ? "#0f172a" : "#ffffff",
color: isDarkMode ? "#f8fafc" : "#0f172a",
border: "1px solid #cbd5e1",
borderRadius: "16px",
transition: "all 0.3s ease"
}}>
<h2>Lecture 9: React State Masterclass</h2>
<div style={{ marginBottom: "20px" }}>
<button
onClick={() => setIsDarkMode(!isDarkMode)}
style={{ padding: "8px 16px", borderRadius: "6px", cursor: "pointer" }}
>
Toggle Theme ({isDarkMode ? "๐ Dark" : "โ๏ธ Light"})
</button>
</div>
<div style={{ fontSize: "24px", fontWeight: "bold", marginBottom: "15px" }}>
Current Score: <span style={{ color: "#2506ad" }}>{count}</span>
</div>
<div style={{ marginBottom: "15px" }}>
<label>Increment Step Size: </label>
<select value={step} onChange={(e) => setStep(Number(e.target.value))}>
<option value={1}>1</option>
<option value={5}>5</option>
<option value={10}>10</option>
</select>
</div>
<div style={{ display: "flex", gap: "10px" }}>
<button onClick={() => setCount(count + step)} style={{ padding: "10px 18px", background: "#059669", color: "#fff", border: "none", borderRadius: "6px", fontWeight: "bold" }}>
+ Add {step}
</button>
<button onClick={() => setCount(count - step)} style={{ padding: "10px 18px", background: "#ef4444", color: "#fff", border: "none", borderRadius: "6px", fontWeight: "bold" }}>
- Subtract {step}
</button>
<button onClick={() => setCount(0)} style={{ padding: "10px 18px", background: "#64748b", color: "#fff", border: "none", borderRadius: "6px" }}>
Reset
</button>
</div>
</div>
);
}