Build your first interactive React application and learn the fundamentals of components, JSX, and state.
Now that you have your development environment set up, let's build your first interactive React application! We'll create a simple counter app that demonstrates the core concepts of React.
If you haven't already created a React project, let's create one now:
# Create a new React project
npx create-react-app my-first-react-app
# Navigate to the project directory
cd my-first-react-app
# Start the development server
npm start
Your React app should now be running at http://localhost:3000.
Let's first understand what Create React App gives us by default. Open src/App.js:
import logo from './logo.svg';
import './App.css';
function App() {
return (
<div className="App">
<header className="App-header">
<img src={logo} className="App-logo" alt="logo" />
<p>
Edit <code>src/App.js</code> and save to reload.
</p>
<a
className="App-link"
href="https://reactjs.org"
target="_blank"
rel="noopener noreferrer"
>
Learn React
</a>
</header>
</div>
);
}
export default App;
App is a React functional componentLet's replace the default content with our own interactive counter app. Replace the content of src/App.js with:
import React, { useState } from 'react';
import './App.css';
function App() {
// Declare a state variable called 'count' with initial value 0
const [count, setCount] = useState(0);
// Function to handle increment
const handleIncrement = () => {
setCount(count + 1);
};
// Function to handle decrement
const handleDecrement = () => {
setCount(count - 1);
};
// Function to reset counter
const handleReset = () => {
setCount(0);
};
return (
<div className="App">
<header className="App-header">
<h1>My First React App</h1>
<div className="counter-container">
<h2>Counter: {count}</h2>
<div className="button-group">
<button onClick={handleDecrement} className="counter-btn">
-
</button>
<button onClick={handleReset} className="counter-btn reset">
Reset
</button>
<button onClick={handleIncrement} className="counter-btn">
+
</button>
</div>
</div>
</header>
</div>
);
}
export default App;
Now let's add some styles to make our app look better. Replace the content of src/App.css with:
.App {
text-align: center;
}
.App-header {
background-color: #282c34;
padding: 40px;
color: white;
min-height: 100vh;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
font-size: calc(10px + 2vmin);
}
.counter-container {
background-color: #3a3f47;
padding: 40px;
border-radius: 15px;
box-shadow: 0 8px 32px rgba(0, 0, 0, 0.3);
margin: 20px;
}
.counter-container h2 {
font-size: 2.5rem;
margin-bottom: 30px;
color: #61dafb;
text-shadow: 0 0 10px rgba(97, 218, 251, 0.3);
}
.button-group {
display: flex;
gap: 15px;
justify-content: center;
align-items: center;
}
.counter-btn {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
border: none;
color: white;
padding: 15px 25px;
font-size: 1.5rem;
border-radius: 10px;
cursor: pointer;
transition: all 0.3s ease;
font-weight: bold;
min-width: 60px;
}
.counter-btn:hover {
transform: translateY(-2px);
box-shadow: 0 5px 15px rgba(102, 126, 234, 0.4);
}
.counter-btn:active {
transform: translateY(0);
}
.counter-btn.reset {
background: linear-gradient(135deg, #f093fb 0%, #f5576c 100%);
min-width: 100px;
}
.counter-btn.reset:hover {
box-shadow: 0 5px 15px rgba(245, 87, 108, 0.4);
}
@media (max-width: 768px) {
.button-group {
flex-direction: column;
}
.counter-btn {
width: 100%;
max-width: 200px;
}
}
Let's break down what we just built:
const [count, setCount] = useState(0);
useState is a React Hook that lets you add state to functional componentscount is the current state valuesetCount is the function to update the state0 is the initial valueconst handleIncrement = () => {
setCount(count + 1);
};
setCount to update the state<button onClick={handleIncrement} className="counter-btn">
+
</button>
onClick is a JSX attribute that binds the click event{handleIncrement} is the function to call when clickedclassName is used instead of class (JavaScript reserved word)<h2>Counter: {count}</h2>
{count} displays the current state value{} let you embed JavaScript expressions in JSXuseState is the most basic hook for managing component stateTry these modifications to understand React better:
function App() {
const [count, setCount] = useState(0);
const [step, setStep] = useState(1);
const handleIncrement = () => {
setCount(count + step);
};
const handleDecrement = () => {
setCount(count - step);
};
return (
<div className="App">
<header className="App-header">
<h1>My First React App</h1>
<div className="counter-container">
<h2>Counter: {count}</h2>
<div className="step-control">
<label>Step: </label>
<input
type="number"
value={step}
onChange={(e) => setStep(Number(e.target.value))}
min="1"
/>
</div>
<div className="button-group">
<button onClick={handleDecrement} className="counter-btn">
-{step}
</button>
<button onClick={() => setCount(0)} className="counter-btn reset">
Reset
</button>
<button onClick={handleIncrement} className="counter-btn">
+{step}
</button>
</div>
</div>
</header>
</div>
);
}
function App() {
const [count, setCount] = useState(0);
// Determine color based on count value
const getCountColor = () => {
if (count > 0) return '#4CAF50'; // Green for positive
if (count < 0) return '#f44336'; // Red for negative
return '#61dafb'; // Blue for zero
};
return (
<div className="App">
<header className="App-header">
<h1>My First React App</h1>
<div className="counter-container">
<h2 style={{ color: getCountColor() }}>
Counter: {count}
</h2>
{/* ... rest of the component */}
</div>
</header>
</div>
);
}
function App() {
const [count, setCount] = useState(0);
const getMessage = () => {
if (count === 0) return "Start counting!";
if (count > 10) return "Wow, that's a lot!";
if (count < -10) return "Going pretty low!";
if (count > 0) return "Positive vibes!";
return "Going negative...";
};
return (
<div className="App">
<header className="App-header">
<h1>My First React App</h1>
<div className="counter-container">
<h2>Counter: {count}</h2>
<p className="message">{getMessage()}</p>
{/* ... buttons */}
</div>
</header>
</div>
);
}
❌ Wrong:
const handleIncrement = () => {
count++; // Don't mutate state directly
};
✅ Correct:
const handleIncrement = () => {
setCount(count + 1); // Use the setter function
};
❌ Wrong:
import React from 'react';
// useState not imported
✅ Correct:
import React, { useState } from 'react';
❌ Wrong:
<button class="counter-btn">Click me</button>
✅ Correct:
<button className="counter-btn">Click me</button>
Open your browser's React Developer Tools (if you installed them) and:
Congratulations! You've built your first interactive React application. Here's what you've accomplished:
✅ Created a functional component with state
✅ Used the useState hook to manage component state
✅ Handled user events with onClick handlers
✅ Applied conditional styling and logic
✅ Structured JSX with proper syntax
✅ Styled your component with CSS
Try building these variations to reinforce your learning:
Create a component that converts between Celsius and Fahrenheit.
Build a single todo item that can be marked as complete/incomplete.
Create a component with buttons that change the background color.
Build an input field that shows a personalized greeting.
In the next lesson, we'll dive deeper into JSX - the syntax that makes React components so powerful and expressive. You'll learn:
Keep experimenting with your counter app and try adding new features. The best way to learn React is by building and breaking things!
App not updating when buttons are clicked?
setCount to update stateuseState from ReactStyles not applying?
Build errors?
Great job building your first React app! You're now ready to explore more advanced React concepts.