React Quick Start
Overview
This chapter will guide you to quickly create your first React application and understand the basic workflow of React. We will start by creating a project and gradually understand the core concepts of React applications, including components, JSX, state management, and more.
🚀 Creating Your First React Application
Project Initialization
bash
# Create new project
npx create-react-app my-first-react-app
# Enter project directory
cd my-first-react-app
# Start development server
npm startProject Structure Analysis
my-first-react-app/
├── public/ # Static assets directory
│ ├── index.html # HTML template
│ ├── favicon.ico # Website icon
│ └── manifest.json # PWA configuration
├── src/ # Source code directory
│ ├── App.js # Main application component
│ ├── App.css # Application styles
│ ├── index.js # Application entry point
│ ├── index.css # Global styles
│ └── App.test.js # Test file
├── package.json # Dependency configuration
└── README.md # Project documentation📝 Understanding Core Files
index.html - HTML Template
html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<link rel="icon" href="%PUBLIC_URL%/favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="theme-color" content="#000000" />
<meta name="description" content="Web site created using create-react-app" />
<title>My First React App</title>
</head>
<body>
<noscript>You need to enable JavaScript to run this app.</noscript>
<!-- React app will mount to this element -->
<div id="root"></div>
<!--
This HTML file is a template.
If you open it directly in the browser, you'll see an empty page.
You can add webfonts, meta tags, or analytics to this file.
The build step will place the bundled scripts into the <body> tag.
-->
</body>
</html>index.js - Application Entry Point
jsx
import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import App from './App';
// Get root element
const root = ReactDOM.createRoot(document.getElementById('root'));
// Render app to root element
root.render(
<React.StrictMode>
<App />
</React.StrictMode>
);
// React.StrictMode helps you:
// 1. Detect unsafe lifecycle methods
2. Warn about usage of deprecated string ref API
3. Warn about usage of deprecated findDOMNode method
4. Detect unexpected side effects
5. Detect outdated context APIApp.js - Main Application Component
jsx
import React from 'react';
import './App.css';
function App() {
return (
<div className="App">
<header className="App-header">
<h1>Welcome to React World!</h1>
<p>This is your first React app</p>
<button onClick={() => alert('Hello React!')}>
Click Me
</button>
</header>
</div>
);
}
export default App;🎯 First Interactive Component
Creating a Counter Component
jsx
import React, { useState } from 'react';
import './App.css';
function Counter() {
// Use useState Hook to manage state
const [count, setCount] = useState(0);
// Event handler functions
const increment = () => {
setCount(count + 1);
};
const decrement = () => {
setCount(count - 1);
};
const reset = () => {
setCount(0);
};
return (
<div className="counter">
<h2>Counter App</h2>
<div className="counter-display">
Current Count: <span className="count-number">{count}</span>
</div>
<div className="counter-buttons">
<button onClick={decrement} className="btn btn-red">
-1
</button>
<button onClick={reset} className="btn btn-gray">
Reset
</button>
<button onClick={increment} className="btn btn-green">
+1
</button>
</div>
</div>
);
}
function App() {
return (
<div className="App">
<header className="App-header">
<h1>My First React App</h1>
<Counter />
</header>
</div>
);
}
export default App;Adding Styles
css
/* App.css */
.App {
text-align: center;
}
.App-header {
background-color: #282c34;
padding: 20px;
color: white;
min-height: 100vh;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
.counter {
background-color: white;
color: #282c34;
padding: 30px;
border-radius: 10px;
margin: 20px;
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
}
.counter-display {
font-size: 24px;
margin: 20px 0;
}
.count-number {
font-weight: bold;
color: #61dafb;
font-size: 32px;
}
.counter-buttons {
display: flex;
gap: 10px;
justify-content: center;
}
.btn {
padding: 10px 20px;
border: none;
border-radius: 5px;
cursor: pointer;
font-size: 16px;
font-weight: bold;
transition: transform 0.2s, box-shadow 0.2s;
}
.btn:hover {
transform: translateY(-2px);
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2);
}
.btn-red {
background-color: #ff6b6b;
color: white;
}
.btn-gray {
background-color: #6c757d;
color: white;
}
.btn-green {
background-color: #51cf66;
color: white;
}🔧 Adding More Features
Todo Component
jsx
import React, { useState } from 'react';
function TodoApp() {
const [todos, setTodos] = useState([]);
const [inputValue, setInputValue] = useState('');
// Add todo
const addTodo = () => {
if (inputValue.trim()) {
const newTodo = {
id: Date.now(),
text: inputValue,
completed: false
};
setTodos([...todos, newTodo]);
setInputValue('');
}
};
// Toggle completion status
const toggleTodo = (id) => {
setTodos(todos.map(todo =>
todo.id === id ? { ...todo, completed: !todo.completed } : todo
));
};
// Delete todo
const deleteTodo = (id) => {
setTodos(todos.filter(todo => todo.id !== id));
};
// Handle keyboard events
const handleKeyPress = (e) => {
if (e.key === 'Enter') {
addTodo();
}
};
return (
<div className="todo-app">
<h2>Todo List</h2>
{/* Input area */}
<div className="todo-input">
<input
type="text"
value={inputValue}
onChange={(e) => setInputValue(e.target.value)}
onKeyPress={handleKeyPress}
placeholder="Enter todo..."
className="todo-input-field"
/>
<button onClick={addTodo} className="btn btn-blue">
Add
</button>
</div>
{/* Todo list */}
<div className="todo-list">
{todos.length === 0 ? (
<p className="no-todos">No todos yet</p>
) : (
todos.map(todo => (
<div
key={todo.id}
className={`todo-item ${todo.completed ? 'completed' : ''}`}
>
<input
type="checkbox"
checked={todo.completed}
onChange={() => toggleTodo(todo.id)}
/>
<span className="todo-text">{todo.text}</span>
<button
onClick={() => deleteTodo(todo.id)}
className="btn btn-small btn-red"
>
Delete
</button>
</div>
))
)}
</div>
{/* Statistics */}
<div className="todo-stats">
<p>Total: {todos.length} | Completed: {todos.filter(t => t.completed).length}</p>
</div>
</div>
);
}
// Update App component
function App() {
const [currentView, setCurrentView] = useState('counter');
return (
<div className="App">
<header className="App-header">
<h1>My React App Collection</h1>
{/* Navigation menu */}
<nav className="app-nav">
<button
onClick={() => setCurrentView('counter')}
className={`nav-btn ${currentView === 'counter' ? 'active' : ''}`}
>
Counter
</button>
<button
onClick={() => setCurrentView('todo')}
className={`nav-btn ${currentView === 'todo' ? 'active' : ''}`}
>
Todo
</button>
</nav>
{/* Show component based on current view */}
{currentView === 'counter' && <Counter />}
{currentView === 'todo' && <TodoApp />}
</header>
</div>
);
}
export default App;Complete Styles
css
/* Add to App.css */
/* Navigation styles */
.app-nav {
margin-bottom: 30px;
}
.nav-btn {
padding: 10px 20px;
margin: 0 10px;
border: 2px solid #61dafb;
background-color: transparent;
color: #61dafb;
border-radius: 5px;
cursor: pointer;
transition: all 0.3s;
}
.nav-btn:hover,
.nav-btn.active {
background-color: #61dafb;
color: #282c34;
}
/* Todo styles */
.todo-app {
background-color: white;
color: #282c34;
padding: 30px;
border-radius: 10px;
margin: 20px;
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
max-width: 500px;
}
.todo-input {
display: flex;
gap: 10px;
margin-bottom: 20px;
}
.todo-input-field {
flex: 1;
padding: 10px;
border: 2px solid #ddd;
border-radius: 5px;
font-size: 16px;
}
.todo-input-field:focus {
outline: none;
border-color: #61dafb;
}
.btn-blue {
background-color: #61dafb;
color: #282c34;
}
.todo-list {
min-height: 200px;
}
.todo-item {
display: flex;
align-items: center;
gap: 10px;
padding: 10px;
border-bottom: 1px solid #eee;
transition: background-color 0.2s;
}
.todo-item:hover {
background-color: #f8f9fa;
}
.todo-item.completed .todo-text {
text-decoration: line-through;
color: #6c757d;
}
.todo-text {
flex: 1;
text-align: left;
}
.btn-small {
padding: 5px 10px;
font-size: 12px;
}
.no-todos {
text-align: center;
color: #6c757d;
font-style: italic;
padding: 40px;
}
.todo-stats {
margin-top: 20px;
padding-top: 20px;
border-top: 1px solid #eee;
font-size: 14px;
color: #6c757d;
}🎨 Understanding React Core Concepts
1. Components
jsx
// Function component - Recommended
function Greeting({ name }) {
return <h1>Hello, {name}!</h1>;
}
// Class component - Traditional
class GreetingClass extends React.Component {
render() {
return <h1>Hello, {this.props.name}!</h1>;
}
}2. JSX Syntax
jsx
function ExampleComponent() {
const user = { name: 'John', age: 25 };
const isLoggedIn = true;
return (
<div>
{/* JavaScript expressions */}
<h1>Username: {user.name}</h1>
<p>Age: {user.age}</p>
{/* Conditional rendering */}
{isLoggedIn ? (
<p>Welcome back!</p>
) : (
<p>Please login first</p>
)}
{/* List rendering */}
<ul>
{['Apple', 'Banana', 'Orange'].map((fruit, index) => (
<li key={index}>{fruit}</li>
))}
</ul>
</div>
);
}3. State Management
jsx
import { useState } from 'react';
function StateExample() {
// Simple state
const [count, setCount] = useState(0);
// Object state
const [user, setUser] = useState({
name: '',
email: ''
});
// Array state
const [items, setItems] = useState([]);
const updateUserName = (newName) => {
setUser(prevUser => ({
...prevUser,
name: newName
}));
};
const addItem = (item) => {
setItems(prevItems => [...prevItems, item]);
};
return (
<div>
<p>Count: {count}</p>
<button onClick={() => setCount(count + 1)}>
Increment
</button>
</div>
);
}4. Event Handling
jsx
function EventExample() {
const [inputValue, setInputValue] = useState('');
// Handle input change
const handleInputChange = (event) => {
setInputValue(event.target.value);
};
// Handle form submission
const handleSubmit = (event) => {
event.preventDefault();
console.log('Submitted value:', inputValue);
};
// Handle keyboard events
const handleKeyDown = (event) => {
if (event.key === 'Enter') {
console.log('Enter key pressed');
}
};
return (
<form onSubmit={handleSubmit}>
<input
type="text"
value={inputValue}
onChange={handleInputChange}
onKeyDown={handleKeyDown}
placeholder="Enter text..."
/>
<button type="submit">Submit</button>
</form>
);
}🔍 Developer Tools Usage
Browser Console Debugging
jsx
function DebugExample() {
const [data, setData] = useState(null);
const fetchData = async () => {
try {
console.log('Starting data fetch...');
const response = await fetch('https://jsonplaceholder.typicode.com/posts/1');
const result = await response.json();
console.log('Fetched data:', result);
setData(result);
} catch (error) {
console.error('Data fetch failed:', error);
}
};
return (
<div>
<button onClick={fetchData}>Fetch Data</button>
{data && (
<div>
<h3>{data.title}</h3>
<p>{data.body}</p>
</div>
)}
</div>
);
}React Developer Tools
jsx
// Add displayName to component for easier debugging
function UserCard({ user }) {
return (
<div className="user-card">
<h3>{user.name}</h3>
<p>{user.email}</p>
</div>
);
}
UserCard.displayName = 'UserCard';
// Use React.memo for performance optimization
const OptimizedUserCard = React.memo(UserCard);🏃♂️ Practice Exercises
Exercise 1: Personal Profile Card
jsx
function ProfileCard() {
const [profile, setProfile] = useState({
name: 'John',
title: 'Frontend Developer',
bio: 'Passionate about coding, focused on React development',
avatar: 'https://via.placeholder.com/150'
});
const [isEditing, setIsEditing] = useState(false);
return (
<div className="profile-card">
{isEditing ? (
<div>
<input
value={profile.name}
onChange={(e) => setProfile({...profile, name: e.target.value})}
/>
<input
value={profile.title}
onChange={(e) => setProfile({...profile, title: e.target.value})}
/>
<textarea
value={profile.bio}
onChange={(e) => setProfile({...profile, bio: e.target.value})}
/>
<button onClick={() => setIsEditing(false)}>Save</button>
</div>
) : (
<div>
<img src={profile.avatar} alt="Avatar" />
<h2>{profile.name}</h2>
<h3>{profile.title}</h3>
<p>{profile.bio}</p>
<button onClick={() => setIsEditing(true)}>Edit</button>
</div>
)}
</div>
);
}Exercise 2: Simple Calculator
jsx
function Calculator() {
const [display, setDisplay] = useState('0');
const [previousValue, setPreviousValue] = useState(null);
const [operation, setOperation] = useState(null);
const [waitingForNewValue, setWaitingForNewValue] = useState(false);
const inputNumber = (num) => {
if (waitingForNewValue) {
setDisplay(String(num));
setWaitingForNewValue(false);
} else {
setDisplay(display === '0' ? String(num) : display + num);
}
};
const inputOperation = (nextOperation) => {
const inputValue = parseFloat(display);
if (previousValue === null) {
setPreviousValue(inputValue);
} else if (operation) {
const currentValue = previousValue || 0;
const newValue = calculate(currentValue, inputValue, operation);
setDisplay(String(newValue));
setPreviousValue(newValue);
}
setWaitingForNewValue(true);
setOperation(nextOperation);
};
const calculate = (firstValue, secondValue, operation) => {
switch (operation) {
case '+': return firstValue + secondValue;
case '-': return firstValue - secondValue;
case '×': return firstValue * secondValue;
case '÷': return firstValue / secondValue;
case '=': return secondValue;
default: return secondValue;
}
};
const performCalculation = () => {
inputOperation('=');
};
const clear = () => {
setDisplay('0');
setPreviousValue(null);
setOperation(null);
setWaitingForNewValue(false);
};
return (
<div className="calculator">
<div className="display">{display}</div>
<div className="buttons">
<button onClick={clear}>AC</button>
<button onClick={() => inputOperation('÷')}>÷</button>
<button onClick={() => inputOperation('×')}>×</button>
<button onClick={() => inputOperation('-')}>-</button>
<button onClick={() => inputNumber(7)}>7</button>
<button onClick={() => inputNumber(8)}>8</button>
<button onClick={() => inputNumber(9)}>9</button>
<button onClick={() => inputOperation('+')}>+</button>
<button onClick={() => inputNumber(4)}>4</button>
<button onClick={() => inputNumber(5)}>5</button>
<button onClick={() => inputNumber(6)}>6</button>
<button onClick={() => inputNumber(1)}>1</button>
<button onClick={() => inputNumber(2)}>2</button>
<button onClick={() => inputNumber(3)}>3</button>
<button onClick={() => inputNumber(0)}>0</button>
<button onClick={performCalculation}>=</button>
</div>
</div>
);
}📝 Chapter Summary
Through this quick start chapter, you should have mastered:
Key Concepts
- ✅ Basic React project structure
- ✅ Component creation and usage
- ✅ JSX syntax basics
- ✅ State management basics
- ✅ Event handling mechanism
- ✅ Basic debugging techniques
Practical Skills
- ✅ Creating interactive components
- ✅ Handling user input
- ✅ Managing application state
- ✅ Styling and layout
- ✅ Conditional rendering and list rendering
Development Process
- Create Project: Use Create React App
- Write Components: Function components + Hooks
- Add Styles: CSS styling
- Test Functionality: Browser debugging
- Iterate Development: Continuous improvement
Next Steps
- Deep dive into React project structure
- Learn more about Hooks usage
- Master component communication
- Learn about routing and state management
Continue Learning: Next Chapter - React Project Structure