Managing data in React can feel like a balancing act, especially when you are building complex dashboards for a fintech startup in New York or a logistics app in Chicago.
In my eight years of working with React, I’ve found that understanding how “state” works in class components is the foundation for everything else.
Even though Functional Components are popular now, many enterprise-level applications in the US still rely heavily on Class Components for their robust structure.
In this tutorial, I’ll walk you through exactly how to handle state in React class components using real-world scenarios you’ll actually encounter.
What is State in React Class Components?
Think of the state as the “memory” of your component. It is a plain JavaScript object that holds information that might change over the lifetime of the component.
When the state changes, React automatically re-renders the component to reflect those changes in the UI.
For example, if you are building a tax calculator for a firm in Texas, the “Total Tax” would be stored in the state because it changes based on the user’s input.
Initialize State in the Constructor
The most traditional way to set up your state is inside the constructor method of your class.
This is where you define the initial values for your data before the component even appears on the screen.
In the example below, let’s imagine we are building a simple “Employee Payroll” toggle for an HR department in Seattle.
import React, { Component } from 'react';
class PayrollTracker extends Component {
constructor(props) {
super(props);
// Initializing the state object
this.state = {
employeeName: "John Doe",
hourlyRate: 45,
isEnrolledIn401k: true,
clockInTime: "9:00 AM"
};
}
render() {
return (
<div style={{ padding: '20px', border: '1px solid #ccc' }}>
<h1>Employee Profile: {this.state.employeeName}</h1>
<p>Hourly Rate: ${this.state.hourlyRate}</p>
<p>401k Status: {this.state.isEnrolledIn401k ? "Enrolled" : "Not Enrolled"}</p>
<p>Scheduled Start: {this.state.clockInTime}</p>
</div>
);
}
}
export default PayrollTracker;You can refer to the screenshot below to see the output.

In this code, we use this.state to hold our data. Remember, you must call super(props) first, or you won’t be able to use this.
Update State Using setState()
You should never modify the state directly (like this.state.name = ‘Smith’). React won’t know that the data changed, so the screen won’t update.
Instead, we use the this.setState() method. This tells React, “Hey, I changed something, please refresh the view.”
Let’s look at a “Sales Commission Tracker” used by a car dealership in Miami. When a salesperson makes a sale, we update the count.
import React, { Component } from 'react';
class SalesCounter extends Component {
constructor(props) {
super(props);
this.state = {
salesCount: 0,
dealershipName: "Miami Premium Motors"
};
}
handleNewSale = () => {
// Updating the state correctly
this.setState({
salesCount: this.state.salesCount + 1
});
}
render() {
return (
<div style={{ textAlign: 'center', marginTop: '50px' }}>
<h2>{this.state.dealershipName}</h2>
<p>Total Cars Sold Today: {this.state.salesCount}</p>
<button
onClick={this.handleNewSale}
style={{ padding: '10px 20px', backgroundColor: '#007bff', color: 'white', border: 'none', cursor: 'pointer' }}
>
Register New Sale
</button>
</div>
);
}
}
export default SalesCounter;You can refer to the screenshot below to see the output.

When you click the button, setState merges the new salesCount into the existing state object and triggers a re-render.
Handle Multiple State Properties
Most of the time, your state will have more than one piece of data.
React’s setState performs a “shallow merge.” This means if you update one property, the others remain untouched.
Suppose we are managing a “Flight Booking” status for a travel agency in Los Angeles.
import React, { Component } from 'react';
class FlightStatus extends Component {
constructor(props) {
super(props);
this.state = {
flightNumber: "UA240",
destination: "San Francisco",
gate: "B12",
status: "On Time"
};
}
delayFlight = () => {
this.setState({
status: "Delayed",
gate: "C15"
});
}
render() {
return (
<div style={{ fontFamily: 'Arial, sans-serif', padding: '30px' }}>
<h3>LAX Departure Board</h3>
<ul>
<li><strong>Flight:</strong> {this.state.flightNumber}</li>
<li><strong>To:</strong> {this.state.destination}</li>
<li><strong>Gate:</strong> {this.state.gate}</li>
<li><strong>Current Status:</strong> {this.state.status}</li>
</ul>
<button onClick={this.delayFlight}>Report Delay</button>
</div>
);
}
}
export default FlightStatus;You can refer to the screenshot below to see the output.

In this example, when delayFlight is called, flightNumber and destination stay exactly as they were.
Use State with User Input (Forms)
One of the most common tasks is capturing what a user types. In React, we call these “Controlled Components.” The state becomes the “single source of truth” for the input field.
Let’s build a “Mailing List Signup” for a boutique coffee shop in Portland.
import React, { Component } from 'react';
class NewsletterSignup extends Component {
constructor(props) {
super(props);
this.state = {
email: "",
zipCode: ""
};
}
handleInputChange = (event) => {
const { name, value } = event.target;
this.setState({
[name]: value
});
}
handleSubmit = (e) => {
e.preventDefault();
alert(`Thank you for signing up! We will send coupons to ${this.state.email} in ZIP ${this.state.zipCode}`);
}
render() {
return (
<form onSubmit={this.handleSubmit} style={{ maxWidth: '400px', margin: '20px auto' }}>
<h3>Portland Roast Newsletter</h3>
<div>
<label>Email Address:</label>
<input
type="email"
name="email"
value={this.state.email}
onChange={this.handleInputChange}
style={{ display: 'block', width: '100%', marginBottom: '10px' }}
/>
</div>
<div>
<label>US ZIP Code:</label>
<input
type="text"
name="zipCode"
value={this.state.zipCode}
onChange={this.handleInputChange}
style={{ display: 'block', width: '100%', marginBottom: '20px' }}
/>
</div>
<button type="submit">Join Community</button>
</form>
);
}
}
export default NewsletterSignup;By using [name]: value, I can handle multiple input fields with a single function. This is a trick I use daily to keep my code clean.
Update State Based on Previous State
Sometimes, the new state depends on the old state. Because setState is asynchronous, using this.state directly inside setState can lead to bugs.
In these cases, you should pass a function to setState instead of an object.
Imagine a “Digital Voting” app for a local election in Denver where votes need to be counted accurately.
import React, { Component } from 'react';
class ElectionVote extends Component {
constructor(props) {
super(props);
this.state = {
votes: 0
};
}
castVote = () => {
// Safe way to update based on previous state
this.setState((prevState) => ({
votes: prevState.votes + 1
}));
}
render() {
return (
<div style={{ padding: '20px', border: '2px solid black', width: '250px' }}>
<h4>Denver District 5</h4>
<p>Current Vote Count: {this.state.votes}</p>
<button onClick={this.castVote}>Submit Ballot</button>
</div>
);
}
}
export default ElectionVote;Using prevState ensures that even if multiple clicks happen quickly, the count remains accurate.
Pass State as Props
In React, data flows down. You can pass the state of a parent component down to a child component as a “prop.”
This is how we build modular apps for large companies where different teams work on different sections.
import React, { Component } from 'react';
// Child Component
class PriceDisplay extends Component {
render() {
return (
<h4 style={{ color: 'green' }}>
Current Price in USD: ${this.props.currentPrice}
</h4>
);
}
}
// Parent Component
class StockTracker extends Component {
constructor(props) {
super(props);
this.state = {
ticker: "AAPL",
price: 150.25
};
}
updatePrice = () => {
// Simulate a price change
const newPrice = (this.state.price + Math.random() * 5).toFixed(2);
this.setState({ price: parseFloat(newPrice) });
}
render() {
return (
<div style={{ padding: '20px' }}>
<h1>Wall Street Tracker</h1>
<p>Trading: {this.state.ticker}</p>
{/* Passing state to child */}
<PriceDisplay currentPrice={this.state.price} />
<button onClick={this.updatePrice}>Refresh Quote</button>
</div>
);
}
}
export default StockTracker;Whenever the StockTracker state changes, the PriceDisplay child component updates automatically.
Key Rules for Using State
Over the years, I’ve developed a few rules of thumb to avoid common pitfalls:
- Don’t Overuse State: If a value can be calculated from props, don’t put it in the state.
- Keep it Flat: Try to avoid deeply nested objects in your state; it makes updates much harder.
- Immutability: Always treat state as read-only. Use setState for every change.
In this guide, I have covered how to initialize, update, and pass state in React class components.
I hope you found this tutorial useful and can apply these examples to your own American-based web projects.
You may also like to read:
- How to Get Props of Component in React
- Create a React ContentEditable Component with Children
- How to Fix React Warning for contentEditable with Children
- How to Manage State in React Using Modern Hooks

I am Bijay Kumar, a Microsoft MVP in SharePoint. Apart from SharePoint, I started working on Python, Machine learning, and artificial intelligence for the last 5 years. During this time I got expertise in various Python libraries also like Tkinter, Pandas, NumPy, Turtle, Django, Matplotlib, Tensorflow, Scipy, Scikit-Learn, etc… for various clients in the United States, Canada, the United Kingdom, Australia, New Zealand, etc. Check out my profile.