Introduction to React
Learn the basics of building user interfaces with React, the popular JavaScript library.
React is a powerful JavaScript library for building user interfaces, particularly single-page applications. Developed and maintained by Facebook (now Meta), React has become one of the most popular front-end libraries due to its efficiency, flexibility, and robust ecosystem.
Why React?
React offers several advantages that have contributed to its popularity:
- Component-Based: React uses reusable components that manage their own state, making it easier to build complex UIs
- Declarative Syntax: You describe what your UI should look like based on the current state, and React efficiently updates the DOM
- Virtual DOM: React’s virtual DOM minimizes DOM operations, resulting in better performance
- One-Way Data Flow: Makes your code more predictable and easier to debug
- Strong Community & Ecosystem: Extensive libraries, tools, and support
Setting Up Your First React Project
The easiest way to start with React is using Create React App, a command-line tool that sets up a new React project with a good default configuration:
# Install Create React App globally (if you haven't already)
npm install -g create-react-app
# Create a new React project
npx create-react-app my-react-app
# Navigate to the project folder
cd my-react-app
# Start the development server
npm start
This will create a new React application and open it in your browser at http://localhost:3000.
React Components
Components are the building blocks of React applications. A component is a JavaScript function or class that returns a React element (typically JSX) that represents a piece of the UI.
Functional Components
Modern React applications primarily use functional components, which are simpler and support hooks:
import React from "react";
function Greeting(props) {
return <h1>Hello, {props.name}!</h1>;
}
export default Greeting;
Class Components
While less common in new code, you might encounter class components in existing projects:
import React, { Component } from "react";
class Greeting extends Component {
render() {
return <h1>Hello, {this.props.name}!</h1>;
}
}
export default Greeting;
JSX: JavaScript + XML
JSX is a syntax extension for JavaScript that looks similar to HTML. It allows you to write HTML-like code in your JavaScript:
const element = <h1>Hello, world!</h1>;
JSX allows you to embed JavaScript expressions using curly braces:
const name = "John";
const element = <h1>Hello, {name}!</h1>;
Important JSX rules to remember:
- JSX elements must have a single root element
- All tags must be closed (either with a closing tag or self-closing)
- Attributes use camelCase (e.g.,
className
instead ofclass
) - JavaScript expressions go inside curly braces
{}
Props: Passing Data to Components
Props (short for properties) are a way to pass data from parent to child components:
// Parent component
function App() {
return <Greeting name="John" age={25} />;
}
// Child component
function Greeting(props) {
return (
<div>
<h1>Hello, {props.name}!</h1>
<p>You are {props.age} years old.</p>
</div>
);
}
State: Managing Component Data
State allows React components to change their output over time in response to user actions, network responses, or anything else.
Using State with Hooks
The useState
hook lets you add state to functional components:
import React, { useState } from "react";
function Counter() {
// Declare a state variable named 'count' with initial value 0
const [count, setCount] = useState(0);
return (
<div>
<p>You clicked {count} times</p>
<button onClick={() => setCount(count + 1)}>Click me</button>
</div>
);
}
Each call to useState
declares a separate state variable. You can use as many state variables as you need:
function UserForm() {
const [firstName, setFirstName] = useState("");
const [lastName, setLastName] = useState("");
const [email, setEmail] = useState("");
// ...
}
Event Handling in React
React events are named using camelCase and passed as functions:
function Button() {
function handleClick() {
alert("Button was clicked!");
}
return <button onClick={handleClick}>Click me</button>;
}
You can pass parameters to event handlers using arrow functions:
function ItemList() {
const items = ["Apple", "Banana", "Cherry"];
function handleItemClick(item) {
alert(`You clicked ${item}`);
}
return (
<ul>
{items.map((item, index) => (
<li key={index} onClick={() => handleItemClick(item)}>
{item}
</li>
))}
</ul>
);
}
Conditional Rendering
In React, you can conditionally render components or elements:
function UserGreeting(props) {
const { isLoggedIn } = props;
// Using ternary operator
return <h1>{isLoggedIn ? "Welcome back!" : "Please sign in."}</h1>;
// Alternative: using &&
// return isLoggedIn && <h1>Welcome back!</h1>;
}
Rendering Lists
You can render lists of items using the map()
function:
function TodoList() {
const todos = [
{ id: 1, text: "Learn React" },
{ id: 2, text: "Build an app" },
{ id: 3, text: "Deploy to production" },
];
return (
<ul>
{todos.map((todo) => (
<li key={todo.id}>{todo.text}</li>
))}
</ul>
);
}
The key
prop is important for helping React identify which items have changed. It should be unique among siblings and stable across renders.
Component Lifecycle with Hooks
The Effect Hook (useEffect
) lets you perform side effects in functional components:
import React, { useState, useEffect } from "react";
function Clock() {
const [time, setTime] = useState(new Date());
useEffect(() => {
// This runs after every render
const timerID = setInterval(() => {
setTime(new Date());
}, 1000);
// Cleanup function that runs before the component unmounts or re-renders
return () => {
clearInterval(timerID);
};
}, []); // Empty dependency array means this effect runs only once after initial render
return (
<div>
<h2>It is {time.toLocaleTimeString()}.</h2>
</div>
);
}
The dependency array (second argument to useEffect
) controls when the effect runs:
- Empty array (
[]
): Run once after initial render - With dependencies (
[dep1, dep2]
): Run when any dependency changes - No array: Run after every render
Forms in React
Working with forms requires managing the form state:
import React, { useState } from "react";
function SimpleForm() {
const [formData, setFormData] = useState({
name: "",
email: "",
});
function handleChange(event) {
const { name, value } = event.target;
setFormData({
...formData,
[name]: value,
});
}
function handleSubmit(event) {
event.preventDefault();
console.log("Form submitted:", formData);
// Submit to an API, etc.
}
return (
<form onSubmit={handleSubmit}>
<div>
<label htmlFor="name">Name:</label>
<input
type="text"
id="name"
name="name"
value={formData.name}
onChange={handleChange}
/>
</div>
<div>
<label htmlFor="email">Email:</label>
<input
type="email"
id="email"
name="email"
value={formData.email}
onChange={handleChange}
/>
</div>
<button type="submit">Submit</button>
</form>
);
}
B[Create Static Components]
B --> C[Identify State Location]
C --> D[Add Interactivity with State & Props]
D --> E[Add Side Effects]
E --> F[Optimize Performance]
F --> G[Deploy]
“ —>
Building a Simple React App
Let’s put everything together in a simple Todo application:
import React, { useState } from "react";
import "./App.css";
function App() {
// State for the todo list and new todo input
const [todos, setTodos] = useState([]);
const [newTodo, setNewTodo] = useState("");
// Add a new todo
function handleAddTodo(event) {
event.preventDefault();
if (newTodo.trim() === "") return;
setTodos([...todos, { id: Date.now(), text: newTodo, completed: false }]);
setNewTodo("");
}
// Toggle todo completion status
function handleToggleTodo(id) {
setTodos(
todos.map((todo) =>
todo.id === id ? { ...todo, completed: !todo.completed } : todo
)
);
}
// Delete a todo
function handleDeleteTodo(id) {
setTodos(todos.filter((todo) => todo.id !== id));
}
return (
<div className="app">
<h1>Todo List</h1>
<form onSubmit={handleAddTodo}>
<input
type="text"
value={newTodo}
onChange={(e) => setNewTodo(e.target.value)}
placeholder="Add a new todo..."
/>
<button type="submit">Add</button>
</form>
<ul className="todo-list">
{todos.length === 0 ? (
<li className="empty-message">No todos yet! Add one above.</li>
) : (
todos.map((todo) => (
<li key={todo.id} className={todo.completed ? "completed" : ""}>
<span onClick={() => handleToggleTodo(todo.id)}>{todo.text}</span>
<button onClick={() => handleDeleteTodo(todo.id)}>Delete</button>
</li>
))
)}
</ul>
</div>
);
}
export default App;
Here’s some basic CSS to style this application:
.app {
max-width: 500px;
margin: 0 auto;
padding: 20px;
font-family: Arial, sans-serif;
}
form {
display: flex;
margin-bottom: 20px;
}
input {
flex-grow: 1;
padding: 10px;
border: 1px solid #ddd;
border-radius: 4px 0 0 4px;
font-size: 16px;
}
button {
padding: 10px 15px;
background-color: #0066ff;
color: white;
border: none;
border-radius: 0 4px 4px 0;
cursor: pointer;
font-size: 16px;
}
.todo-list {
list-style-type: none;
padding: 0;
}
.todo-list li {
display: flex;
justify-content: space-between;
align-items: center;
padding: 10px;
margin-bottom: 10px;
background-color: #f9f9f9;
border-radius: 4px;
}
.completed span {
text-decoration: line-through;
color: #888;
}
.todo-list button {
background-color: #ff3333;
border-radius: 4px;
}
.empty-message {
color: #888;
text-align: center;
}
Next Steps in Your React Journey
After mastering the basics, you can expand your React knowledge with:
- React Router - For handling navigation in single-page applications
- State Management - Libraries like Redux or Zustand for complex state management
- Context API - React’s built-in solution for sharing state
- Custom Hooks - Building reusable logic
- React Testing - Using React Testing Library or Jest
- Performance Optimization - Memoization with
useMemo
anduseCallback
- Server-Side Rendering - With frameworks like Next.js
Conclusion
React has revolutionized the way we build user interfaces by providing a component-based approach that is both powerful and flexible. By breaking down your UI into small, reusable components, you can create complex applications that are easier to maintain and update.
Remember that the best way to learn React is by building projects. Start with small applications and gradually take on more complex challenges as you become more comfortable with the library’s patterns and practices.
With its strong community support and extensive ecosystem, React continues to evolve and improve, making it an excellent choice for modern web development.