Welcome back to the React Mastery Series!
In the previous article, we explored Props, which allow parent components to pass data to child components.
But what happens when the data needs to change over time?
Think about applications you use every day:
- A shopping cart where items are added or removed.
- A banking app where the account balance updates after a transaction.
- A social media app where the number of likes increases instantly.
- A to-do app where tasks are marked as completed.
These applications are interactive because they use State.
Today, we'll understand one of the most fundamental concepts in React—State.
What is State?
State is data that belongs to a component and can change over time.
Unlike props, which are passed from a parent component and are read-only, state is owned and managed by the component itself.
When state changes, React automatically re-renders the component to reflect the updated UI.
Think of state as the component's memory.
Why Do We Need State?
Imagine building a counter application.
Without state:
function Counter() {
let count = 0;
return (
<>
<h2>{count}</h2>
<button>Increment</button>
</>
);
}
Clicking the button won't change the displayed value because React doesn't know that count has changed.
To make the UI reactive, React provides State.
Introducing the useState Hook
In functional components, state is managed using the useState Hook.
import { useState } from "react";
function Counter() {
const [count, setCount] = useState(0);
return (
<>
<h2>{count}</h2>
<button
onClick={() => setCount(count + 1)}
>
Increment
</button>
</>
);
}
When the button is clicked:
-
setCount()updates the state. - React schedules a re-render.
- The updated value appears on the screen.
No manual DOM manipulation is required.
Understanding useState
const [count, setCount] = useState(0);
Let's break it down.
count → Current state value
setCount → Function used to update state
0 → Initial state value
Every time setCount() is called, React updates the state and re-renders the component.
State Drives the UI
A key React principle is:
The UI is a function of State.
Consider a login screen.
isLoggedIn = false
↓
Show Login Button
After authentication:
isLoggedIn = true
↓
Show Dashboard
The UI changes automatically because the underlying state has changed.
Updating State
Always use the setter function returned by useState.
Correct:
setCount(count + 1);
Incorrect:
count = count + 1;
Directly modifying the state variable does not notify React, so the UI will not update.
Updating State Based on Previous State
Sometimes multiple state updates happen close together.
Instead of:
setCount(count + 1);
Prefer the functional update form:
setCount((previousCount) => previousCount + 1);
Why?
Because React may batch state updates for better performance.
Using the previous state guarantees you're working with the latest value.
State Can Store Any JavaScript Value
State isn't limited to numbers.
String
const [name, setName] = useState("Siva");
Boolean
const [isLoggedIn, setIsLoggedIn] =
useState(false);
Array
const [tasks, setTasks] = useState([]);
Object
const [user, setUser] = useState({
name: "Siva",
city: "Dubai",
});
Updating Objects in State
Never modify an object directly.
Incorrect:
user.name = "John";
Correct:
setUser({
...user,
name: "John",
});
The spread operator copies the existing object while updating only the required property.
Updating Arrays in State
Similarly, avoid mutating arrays.
Incorrect:
tasks.push("Learn React");
Correct:
setTasks([
...tasks,
"Learn React",
]);
Creating a new array ensures React detects the change.
Multiple State Variables
A component can manage multiple pieces of state.
const [name, setName] = useState("");
const [email, setEmail] = useState("");
const [age, setAge] = useState(0);
Each state variable is independent.
This makes components easier to reason about.
A Real-World Example
Imagine a banking dashboard.
Account Balance
₹25,000
After transferring money:
Account Balance
₹18,000
The balance displayed on the screen changes because the component's state has been updated.
React automatically re-renders only the affected parts of the UI.
Common Mistakes
Directly Modifying State
❌
count++;
Always use the setter function.
Mutating Objects or Arrays
Avoid using methods like:
push()pop()splice()
Instead, create new objects or arrays using the spread operator or other immutable methods.
Too Much State
Not every value belongs in state.
If a value can be derived from existing state or props, don't duplicate it.
Keeping state minimal reduces bugs and simplifies your code.
State vs Props
| Props | State |
|---|---|
| Passed from parent | Owned by component |
| Read-only | Can change |
| External data | Internal data |
| Cannot be modified by child | Updated using setter functions |
Understanding the distinction between props and state is essential for building predictable React applications.
Best Practices
- Keep state as small as possible.
- Never mutate state directly.
- Use functional updates when the next value depends on the previous one.
- Store only what truly needs to change.
- Split unrelated pieces of state into separate variables.
These practices lead to cleaner, more maintainable components.
Key Takeaways
Today, we learned:
✅ State stores data that changes over time.
✅ Functional components use the useState Hook to manage state.
✅ Updating state triggers a re-render.
✅ State can store any JavaScript value.
✅ Objects and arrays should be updated immutably.
✅ Understanding the difference between props and state is fundamental to React.
Coming Next 🚀
In Day 8, we'll explore one of React's most powerful concepts:
Component Rendering Lifecycle & Re-rendering
We'll answer questions like:
- What happens when a React component renders?
- What triggers a re-render?
- When does React skip rendering?
- What is the rendering lifecycle in functional components?
- How does React decide what to update?
Understanding the rendering process is the foundation for learning performance optimization techniques such as React.memo, useMemo, and useCallback later in this series.
Happy Coding! 🚀
Top comments (0)