Introduction: Why React?

As of 2026, React continues to dominate the frontend development landscape. According to the Stack Overflow 2025 Developer Survey, React holds approximately 42% of the global frontend framework market share, maintaining its first-place position. Vue.js (about 18%), Angular (about 15%), and Svelte (about 8%) follow behind, but the gap with React remains significant. In the domestic (Korean) job market as well, React-related positions account for more than 60% of frontend job postings, establishing React as an essential skill for frontend developers.

The reason to learn React goes beyond its high market share. The vast ecosystem surrounding React provides developers with nearly limitless possibilities. Meta frameworks and mobile development tools built on React, such as Next.js, React Native, and Remix, are actively evolving, and there are tens of thousands of React-related packages registered on npm. Additionally, React boasts one of the most active developer communities in the world, making it easy to find resources and help for problem-solving.

This article guides you step by step from React's core concepts to real-world projects, written so that even complete beginners without a computer science background can understand. By following this guide to the end, you'll understand React's fundamental principles and be able to build a simple web application on your own.

1. React Fundamentals

1.1 What is React?

React is a JavaScript library for building user interfaces (UI) that was open-sourced by Facebook (now Meta) in 2013. To be precise, React is a library, not a framework. Unlike Angular, which has built-in routing, state management, HTTP communication, and more, React focuses on one purpose: UI rendering. The remaining functionality is handled by combining third-party libraries. Thanks to this philosophy, React is lightweight, flexible, and applicable to a wide variety of projects.

There are two core concepts you must understand to grasp React:

  • Virtual DOM: Directly manipulating the browser's real DOM (Document Object Model) is not performant. React maintains a virtual DOM tree in memory, and when state changes, it first calculates the differences in the virtual DOM, then applies only the minimal changes to the real DOM. This process is called Reconciliation, and it enables fast and efficient UI updates.
  • Component-Based Architecture: In React, the UI is built by dividing it into small, independent, and reusable units called Components. A button, a search bar, or a navigation bar can each be a component, and these components are combined to create complex screens. It's similar to assembling LEGO blocks.

1.2 Understanding SPA (Single Page Application)

Web applications built with React mostly operate as SPAs (Single Page Applications). Traditional websites fetch a completely new HTML page from the server and redraw the entire screen every time you navigate to a new page, but SPAs load the full page only once initially and then dynamically update only parts of the screen by fetching just the necessary data from the server. This allows users to enjoy a fast and smooth experience, much like using a desktop application.

Most modern web services we use daily, such as Gmail, Facebook, Instagram, and Netflix, are built as SPAs. The key advantage of SPAs is providing a smooth user experience without page flickering during transitions. The drawback is that initial loading times can be longer and additional effort is needed for search engine optimization (SEO). The latter issue is being addressed by frameworks like Next.js through server-side rendering (SSR).

1.3 Quick Comparison: React vs Vue vs Angular

When starting frontend development, many people struggle with which technology to choose. Let's briefly compare the three major frameworks/libraries:

Category React Vue.js Angular
Developer Meta (Facebook) Evan You (Community) Google
Type Library Framework Framework
Learning Curve Medium Low High
Ecosystem Very broad Broad Broad (many built-in features)
Language JavaScript / JSX JavaScript / SFC TypeScript
Job Market Most demand Growing trend Enterprise-focused
Leading Meta Framework Next.js, Remix Nuxt.js Angular Universal

In conclusion, React is the most versatile choice in terms of job market, ecosystem, and flexibility, making it ideal as your first frontend technology. Vue.js has the lowest entry barrier for those who want to get started quickly, while Angular is suited for large-scale enterprise projects that require a structured architecture.

2. Setting Up the Development Environment

2.1 Installing Node.js

To start React development, you first need to install Node.js. Node.js is a runtime environment that allows JavaScript to run outside the browser and is essential for using React project build tools and the package manager (npm).

Visit the Node.js official website and download and install the LTS (Long Term Support) version. Once installation is complete, verify the installation by running the following commands in your terminal (command prompt):

# Check Node.js version
node -v
# Example output: v22.x.x

# Check npm version
npm -v
# Example output: 10.x.x

2.2 Creating a Project

As of 2026, the standard way to create a React project is to use Vite. In the past, Create React App (CRA) was recommended as the official tool, but it is no longer maintained, and the official React documentation now recommends Vite. Vite has extremely fast build speeds, and its development server's Hot Module Replacement (HMR) is applied almost instantly, providing an excellent development experience.

# Create a React project using Vite
npx create-vite@latest my-first-react-app --template react

# Navigate to the project folder
cd my-first-react-app

# Install dependency packages
npm install

# Start the development server
npm run dev

After running the commands above, your React app will be running at http://localhost:5173. If you see the default screen with the React logo in your browser, you're all set. The generated project's folder structure looks like this:

my-first-react-app/
├── node_modules/       # Installed packages (do not modify directly)
├── public/             # Static files (favicon, etc.)
├── src/                # Source code (development happens here)
│   ├── App.css         # App component styles
│   ├── App.jsx         # Main App component
│   ├── index.css       # Global styles
│   └── main.jsx        # App entry point
├── index.html          # HTML template
├── package.json        # Project configuration and dependency list
└── vite.config.js      # Vite configuration file

The most important folder is src/. All future development work takes place inside this folder. main.jsx is the app's entry point, and this file renders the App.jsx component.

2.3 Recommended VS Code Extensions

Here are some VS Code extensions that make React development more pleasant:

  • ES7+ React/Redux/React-Native snippets: Just type rfce and the basic structure of a function component is auto-generated. It dramatically speeds up your coding.
  • Prettier - Code formatter: Automatically formats your code every time you save. It's essential for unifying code style in team projects.
  • ESLint: Detects syntax errors and potential bugs in JavaScript/JSX code in real-time.
  • Auto Rename Tag: When you modify an opening tag in HTML/JSX, the closing tag is automatically updated as well.
  • Thunder Client: A lightweight REST client that lets you test API requests right inside VS Code.

3. React Core Syntax

3.1 JSX - Where HTML Meets JavaScript

JSX (JavaScript XML) is the syntax used in React for writing UI, combining HTML and JavaScript. It may seem unfamiliar at first, but once you get used to it, it becomes very convenient for intuitively expressing UI structures. Since browsers cannot directly understand JSX, Vite (internally using Babel/SWC) transpiles it into plain JavaScript.

// Basic JSX syntax example
function Greeting() {
  const userName = "Hong Gildong";
  const isLoggedIn = true;

  return (
    <div className="greeting">
      {/* Using JavaScript expressions inside JSX: curly braces {} */}
      <h1>Hello, {userName}!</h1>
      <p>Current time: {new Date().toLocaleTimeString()}</p>

      {/* Conditional rendering: ternary operator */}
      {isLoggedIn ? (
        <p>Welcome! You are logged in.</p>
      ) : (
        <p>Please log in.</p>
      )}

      {/* Conditional rendering: && operator */}
      {isLoggedIn && <button>Log Out</button>}
    </div>
  );
}

There are a few rules to keep in mind when writing JSX:

  • You must wrap everything in a single root element. To return multiple elements, wrap them in a <div> or <>...</> (Fragment).
  • Use className instead of HTML's class (because class is a reserved word in JavaScript).
  • Use htmlFor instead of HTML's for.
  • All tags must be closed (<img />, <br />).
  • JavaScript expressions are written inside {} curly braces.

3.2 Components

In React, components are independent, reusable pieces of code that make up the UI. As of 2026, writing React components as Function Components is the standard. Class components from the past are only found in legacy projects and are not used in new projects.

// Basic function component
function Welcome() {
  return <h1>Hello, React!</h1>;
}

// Component that receives props
function UserCard({ name, email, role }) {
  return (
    <div className="user-card">
      <h2>{name}</h2>
      <p>Email: {email}</p>
      <p>Role: {role}</p>
    </div>
  );
}

// Layout component using children
function Card({ title, children }) {
  return (
    <div className="card">
      <div className="card-header">
        <h3>{title}</h3>
      </div>
      <div className="card-body">
        {children}
      </div>
    </div>
  );
}

// Composing components
function App() {
  return (
    <div>
      <Welcome />
      <Card title="User Info">
        <UserCard
          name="Kim Developer"
          email="dev@example.com"
          role="Frontend Developer"
        />
      </Card>
    </div>
  );
}

Props (Properties) are the way to pass data from a parent component to a child component. They work like function parameters, and props cannot be directly modified inside the child component (they are read-only). children is a special prop that receives whatever content is placed between the opening and closing tags of a component.

3.3 State and Events

State is dynamic data managed within a component. User inputs, data fetched from servers, and UI states (open/closed, etc.) are all examples of state. In React, state is managed using the useState Hook. When state changes, React automatically re-renders the component to update the screen.

import { useState } from 'react';

function Counter() {
  // useState: [current state value, function to update state]
  const [count, setCount] = useState(0);
  const [step, setStep] = useState(1);

  const increment = () => setCount(count + step);
  const decrement = () => setCount(count - step);
  const reset = () => setCount(0);

  return (
    <div className="counter">
      <h2>Counter App</h2>
      <p className="count-display">Current value: {count}</p>

      <div className="controls">
        <label>
          Step size:
          <input
            type="number"
            value={step}
            onChange={(e) => setStep(Number(e.target.value))}
            min="1"
          />
        </label>
      </div>

      <div className="buttons">
        <button onClick={decrement}>-{step}</button>
        <button onClick={reset}>Reset</button>
        <button onClick={increment}>+{step}</button>
      </div>
    </div>
  );
}

export default Counter;

In the example above, useState(0) creates a state with an initial value of 0. count is the current state value, and setCount is the function to update the state. Handler functions are connected to button onClick events, so when a button is clicked, the state changes and the screen is automatically refreshed. The onChange event is called whenever the input field value changes.

3.4 useEffect - Managing Side Effects

useEffect is a Hook for handling "side effects" that are not directly related to a component's rendering. API calls, timer setup, event listener registration, and direct DOM manipulation are all examples of side effects.

import { useState, useEffect } from 'react';

function UserProfile({ userId }) {
  const [user, setUser] = useState(null);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState(null);

  useEffect(() => {
    // API call (async handling)
    const fetchUser = async () => {
      try {
        setLoading(true);
        const response = await fetch(
          `https://jsonplaceholder.typicode.com/users/${userId}`
        );
        if (!response.ok) throw new Error('User not found');
        const data = await response.json();
        setUser(data);
      } catch (err) {
        setError(err.message);
      } finally {
        setLoading(false);
      }
    };

    fetchUser();

    // Cleanup function: runs when the component unmounts or dependencies change
    return () => {
      console.log('Cleanup executed');
    };
  }, [userId]); // Dependency array: re-run useEffect whenever userId changes

  if (loading) return <p>Loading...</p>;
  if (error) return <p>Error: {error}</p>;
  if (!user) return null;

  return (
    <div>
      <h2>{user.name}</h2>
      <p>Email: {user.email}</p>
      <p>Phone: {user.phone}</p>
    </div>
  );
}

The second argument of useEffect, the Dependency Array, is very important. Passing an empty array [] makes it run only once when the component first mounts. Including specific values causes it to re-run whenever those values change. Omitting the dependency array entirely causes it to run on every render, so be careful.

3.5 Conditional Rendering and Lists

In real applications, it's very common to show different UI based on conditions or to display array data as a list.

function FruitList() {
  const fruits = [
    { id: 1, name: "Apple", emoji: "🍎", inStock: true },
    { id: 2, name: "Banana", emoji: "🍌", inStock: true },
    { id: 3, name: "Grape", emoji: "🍇", inStock: false },
    { id: 4, name: "Strawberry", emoji: "🍓", inStock: true },
  ];

  return (
    <div>
      <h2>Fruit List</h2>
      <ul>
        {fruits.map((fruit) => (
          <li key={fruit.id}>
            {fruit.emoji} {fruit.name}
            {fruit.inStock ? (
              <span style={{ color: "green" }}> - In Stock</span>
            ) : (
              <span style={{ color: "red" }}> - Out of Stock</span>
            )}
          </li>
        ))}
      </ul>
      <p>Fruits in stock: {fruits.filter(f => f.inStock).length}</p>
    </div>
  );
}

map() is used to transform each element of an array into a component for rendering a list. When doing so, you must always pass a unique key prop to each element. React uses this key to efficiently determine which items have been added, removed, or changed. It's best to use a unique data ID rather than the array index as the key.

4. Hands-On Project: Building a Todo App

4.1 Project Design

Let's apply all the React core concepts we've learned so far to build a practical Todo app. Through this project, you'll practice component design, state management, event handling, list rendering, and conditional rendering comprehensively. The features to implement are:

  • Add new todos
  • Toggle todo completion status
  • Delete todos
  • Display the remaining todo count

4.2 Component Structure

We'll design the Todo app's components with the following separation:

App (Root component - manages all state)
├── TodoForm (Todo input form)
├── TodoList (Todo list container)
│   └── TodoItem (Individual todo item) x N
└── TodoFooter (Remaining todo count display)

4.3 State Management

The state to manage in this app is the todo list array (todos). Each todo item has an id, text (content), and completed (completion status). All CRUD functions are implemented as state-changing functions in the App component and passed to child components via props.

4.4 Implementing CRUD Features

Below is the complete source code for the Todo app. Enter the following code in the src/App.jsx file and save it to see it working in your browser immediately:

// src/App.jsx - Complete Todo App Code
import { useState } from 'react';

// ─── TodoForm Component ─────────────────────────
function TodoForm({ onAdd }) {
  const [inputValue, setInputValue] = useState('');

  const handleSubmit = (e) => {
    e.preventDefault(); // Prevent default form behavior (page refresh)
    const trimmed = inputValue.trim();
    if (!trimmed) return; // Prevent empty submissions
    onAdd(trimmed);
    setInputValue(''); // Clear the input field
  };

  return (
    <form onSubmit={handleSubmit} className="todo-form">
      <input
        type="text"
        value={inputValue}
        onChange={(e) => setInputValue(e.target.value)}
        placeholder="Enter a todo..."
      />
      <button type="submit">Add</button>
    </form>
  );
}

// ─── TodoItem Component ─────────────────────────
function TodoItem({ todo, onToggle, onDelete }) {
  return (
    <li className={`todo-item ${todo.completed ? 'completed' : ''}`}>
      <input
        type="checkbox"
        checked={todo.completed}
        onChange={() => onToggle(todo.id)}
      />
      <span
        style={{
          textDecoration: todo.completed ? 'line-through' : 'none',
          color: todo.completed ? '#999' : '#333',
        }}
      >
        {todo.text}
      </span>
      <button onClick={() => onDelete(todo.id)}>Delete</button>
    </li>
  );
}

// ─── TodoList Component ─────────────────────────
function TodoList({ todos, onToggle, onDelete }) {
  if (todos.length === 0) {
    return <p className="empty-message">No todos registered.</p>;
  }

  return (
    <ul className="todo-list">
      {todos.map((todo) => (
        <TodoItem
          key={todo.id}
          todo={todo}
          onToggle={onToggle}
          onDelete={onDelete}
        />
      ))}
    </ul>
  );
}

// ─── App Component (Main) ─────────────────────────
function App() {
  const [todos, setTodos] = useState([
    { id: 1, text: 'Study React basic syntax', completed: false },
    { id: 2, text: 'Build a Todo app', completed: false },
    { id: 3, text: 'Push project to Git', completed: false },
  ]);

  // Add todo (Create)
  const addTodo = (text) => {
    const newTodo = {
      id: Date.now(), // Generate unique ID
      text,
      completed: false,
    };
    setTodos([...todos, newTodo]);
  };

  // Toggle completion (Update)
  const toggleTodo = (id) => {
    setTodos(
      todos.map((todo) =>
        todo.id === id
          ? { ...todo, completed: !todo.completed }
          : todo
      )
    );
  };

  // Delete todo (Delete)
  const deleteTodo = (id) => {
    setTodos(todos.filter((todo) => todo.id !== id));
  };

  // Calculate remaining todo count
  const remainingCount = todos.filter((t) => !t.completed).length;

  return (
    <div className="todo-app">
      <h1>My Todo List</h1>
      <TodoForm onAdd={addTodo} />
      <TodoList
        todos={todos}
        onToggle={toggleTodo}
        onDelete={deleteTodo}
      />
      <p className="todo-footer">
        Remaining todos: <strong>{remainingCount}</strong>
      </p>
    </div>
  );
}

export default App;
Key Code Points Summary

1. Immutability: Instead of directly modifying the state array (using push, splice, etc.), always create a new array and pass it to setTodos. Use the spread operator (...), map(), and filter().

2. Unidirectional Data Flow: State is managed in App, and data and functions are passed to child components via props. Children call the passed functions to change the parent's state.

3. Importance of key: When rendering a list with map(), assign a unique key to each item so React can efficiently update the DOM.

5. The React Ecosystem at a Glance

Since React itself is a library focused on UI rendering, real-world projects typically use various third-party libraries alongside it. Here's a categorized overview of the rich ecosystem surrounding React.

Category Key Tools Features Recommended For
Routing React Router v7 Implements page navigation in SPAs, supports nested routes All SPA projects
State Management Zustand Lightweight and intuitive, minimal boilerplate Small to medium projects (currently most popular)
Redux Toolkit Predictable state management, rich middleware Large enterprise projects
Jotai / Recoil Atom-based, React-friendly Complex async state management
Styling Tailwind CSS Utility-first, rapid prototyping Most projects (currently most popular)
styled-components CSS-in-JS, component-level style encapsulation Building design systems
Data Fetching TanStack Query (React Query) Server state management, caching, auto refetch Projects with heavy API communication
Form Management React Hook Form + Zod Performance optimization, schema-based validation Admin pages with complex forms
Server-Side Frameworks Next.js SSR, SSG, API routes, file-based routing SEO-critical projects, full-stack development
Remix Web standards-focused, progressive enhancement Projects committed to web standards
Testing Vitest + Testing Library Fast testing based on Vite, user-perspective testing All projects (testing is essential)

At the beginner stage, you don't need to learn all of the above tools. First, get thoroughly familiar with React itself, and then add tools one by one as your project needs them. As your first external tools, we recommend React Router (page navigation) and Tailwind CSS (styling).

6. Learning Roadmap and Next Steps

6.1 4-Week Learning Roadmap

Here's a suggested 4-week roadmap for systematically learning React. This is based on 1-2 hours of study per day:

Week Topics Goals Practice Projects
Week 1 JavaScript ES6+, React basics Understand arrow functions, destructuring, spread operator, JSX, components, props Build an intro card
Week 2 State, events, useEffect useState, event handling, side effect management, conditional rendering, lists Counter app, Todo app
Week 3 React Router, API integration Page routing, fetch/axios, loading/error handling Movie search app, weather app
Week 4 Styling, deployment Tailwind CSS, responsive design, Vercel/Netlify deployment Build and deploy a portfolio site
Warning: Learn JavaScript Basics First!
Before learning React, you need to have a solid understanding of JavaScript fundamentals, especially ES6+ syntax (arrow functions, destructuring assignment, template literals, array methods map/filter/reduce, Promises, async/await). If you dive straight into React without JavaScript basics, you'll find yourself stuck not because of React itself, but because of JavaScript syntax.

6.2 Recommended Learning Resources

Here are resources organized by priority to help with React learning:

  • React Official Documentation (react.dev): Completely rewritten in 2023, the official docs include interactive tutorials and rich examples, making them the best learning resource. They also offer translations in multiple languages. Be sure to use this as your first study material.
  • Free Online Courses: Platforms like Nomad Coders (Korean), freeCodeCamp (English), and Scrimba (English, interactive) offer quality free React courses.
  • Paid Courses: You can take structured and in-depth React courses on platforms like Udemy and Inflearn. It's best to choose courses that are project-based.
  • Books: "Modern React Deep Dive" by Yongchan Kim - A domestic (Korean) book that covers React's internal workings in depth, suitable for advanced learning beyond the basics.
  • Community: You can communicate and grow with other developers through GitHub, Stack Overflow, Discord (Reactiflux), and other communities.

6.3 Portfolio Project Ideas

After mastering React basics, here are project ideas organized by difficulty that you can include in your portfolio:

  • Beginner: Weather app (using OpenWeatherMap API), notepad app (localStorage storage), timer/stopwatch app, calculator app
  • Intermediate: Movie information search app (TMDB API, infinite scroll), blog platform (markdown editor, category sorting), expense tracker app (using chart libraries), chat app (WebSocket or Firebase)
  • Advanced: E-commerce shopping mall (shopping cart, payment integration, admin page), project management tool (Kanban board, drag and drop), social media feed (infinite scroll, image upload, comments)

Following these practices when working on projects will significantly improve your portfolio quality:

  • Upload your code to GitHub and write a thorough README.md (include project description, tech stack, installation instructions, and screenshots).
  • Deploy to Vercel or Netlify and provide a live accessible URL.
  • Apply responsive design so it looks great on mobile devices too.
  • Writing test code, even if minimal, can be a major differentiator.

Conclusion: React - Getting Started is Half the Battle

React may feel overwhelming at first with its many new concepts (JSX, Virtual DOM, Components, State, Hooks). However, as you learn them one by one at your own pace, you'll naturally come to understand why React is beloved by developers worldwide. React's declarative programming approach and component-based architecture provide a powerful foundation for systematically managing complex UIs.

What matters most is learning by writing code yourself. You can never master programming through theory alone. Type out the counter app and Todo app code from this article yourself and run them. Experiment by modifying the code and observing how the results change. When errors occur, read the error messages, search for solutions, and fix them. This process itself is the most effective form of learning.

As of 2026, React has grown beyond a simple UI library into a standard for frontend development and, through Next.js, a massive ecosystem that encompasses full-stack development. If you start learning React now, you're standing at the doorway to the widest range of possibilities.

3 Steps to Start React Today

Step 1: Install Node.js and create your first project with npx create-vite@latest my-app --template react. It takes just 5 minutes.

Step 2: Type the counter app code from this article into src/App.jsx yourself and verify it works in your browser. We recommend typing it yourself rather than copy-pasting.

Step 3: Enter the Todo app code and try adding features one by one. For example, implementing "todo editing," "filtering completed todos," or "saving to localStorage" on your own is the best way to learn.