Skip to content

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 start

Project 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 API

App.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

  1. Create Project: Use Create React App
  2. Write Components: Function components + Hooks
  3. Add Styles: CSS styling
  4. Test Functionality: Browser debugging
  5. 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

Content is for learning and research only.