reactjavascripttutorialfreshers

React JS Tutorial for Beginners 2026: Build Your First App Step by Step

Siva Prasad Galaba· Staff Engineer at Crunchyroll | Founder, CodeBegun·

Complete React JS tutorial for beginners in 2026. Learn components, props, state, hooks, and API calls by building a real Student List app from scratch.

React is the most in-demand frontend framework in 2026, and it's not close. If you're learning Java Full Stack development, React is the frontend skill that pairs with your Spring Boot API. This tutorial gets you writing real React code in the next 30 minutes.

What You'll Build

A Student List app that:

  • Fetches students from an API
  • Displays them in a list with name, email, and city
  • Has an Add Student form
  • Shows a loading state while fetching

Prerequisites

  • Basic JavaScript (variables, functions, arrays, objects, fetch API)
  • Node.js installed (v18+)
  • A code editor (VS Code recommended)

Step 1 — Create a React Project

npm create vite@latest student-app -- --template react
cd student-app
npm install
npm run dev

Open http://localhost:5173. You should see the Vite + React starter page. That's your dev server running. It hot-reloads on every save.

Step 2 — Understand the Project Structure

student-app/
├── src/
│   ├── App.jsx          ← Your main component
│   ├── main.jsx         ← Entry point (renders App into the DOM)
│   └── App.css          ← Styles
├── index.html           ← Single HTML file
└── package.json

React renders everything into one <div id="root"> in index.html. Your entire app is JavaScript rendering into that div.

Step 3 — Your First Component

Replace everything in src/App.jsx with:

function App() {
  return (
    <div>
      <h1>Student List</h1>
      <p>Welcome to the Student Manager</p>
    </div>
  );
}

export default App;

Save. The browser updates instantly. That's JSX — it looks like HTML but it's JavaScript.

Key JSX rules:

  • Every component returns one root element (or use <>...</> Fragment)
  • Use className instead of class (class is a JavaScript keyword)
  • JavaScript expressions go inside {}

Step 4 — Props: Passing Data to Components

Create a new file src/StudentCard.jsx:

function StudentCard({ name, email, city }) {
  return (
    <div style={{ border: "1px solid #ddd", padding: "12px", marginBottom: "8px", borderRadius: "8px" }}>
      <h3 style={{ margin: "0 0 4px" }}>{name}</h3>
      <p style={{ margin: 0, color: "#666" }}>{email}</p>
      <span style={{ fontSize: "12px", color: "#999" }}>{city}</span>
    </div>
  );
}

export default StudentCard;

Use it in App.jsx:

import StudentCard from "./StudentCard";

function App() {
  return (
    <div style={{ maxWidth: "600px", margin: "40px auto", padding: "0 16px" }}>
      <h1>Student List</h1>
      <StudentCard name="Priya Reddy" email="priya@example.com" city="Hyderabad" />
      <StudentCard name="Ravi Kumar" email="ravi@example.com" city="Vijayawada" />
    </div>
  );
}

Props are how parent components pass data to child components. They flow one way: parent → child.

Step 5 — State with useState

State is data that, when it changes, causes the component to re-render.

Update App.jsx:

import { useState } from "react";
import StudentCard from "./StudentCard";

function App() {
  const [students, setStudents] = useState([
    { id: 1, name: "Priya Reddy", email: "priya@example.com", city: "Hyderabad" },
    { id: 2, name: "Ravi Kumar", email: "ravi@example.com", city: "Vijayawada" },
  ]);

  return (
    <div style={{ maxWidth: "600px", margin: "40px auto", padding: "0 16px" }}>
      <h1>Student List ({students.length})</h1>
      {students.map((student) => (
        <StudentCard
          key={student.id}
          name={student.name}
          email={student.email}
          city={student.city}
        />
      ))}
    </div>
  );
}

export default App;

useState(initialValue) returns two things:

  1. The current state value
  2. A function to update it

Whenever you call setStudents(...), React re-renders the component with the new value.

Always use .map() with a key prop when rendering lists — React needs the key to track which item is which.

Step 6 — useEffect: Running Code After Render

useEffect runs side effects — things that happen outside the component like API calls, timers, subscriptions.

import { useState, useEffect } from "react";
import StudentCard from "./StudentCard";

function App() {
  const [students, setStudents] = useState([]);
  const [loading, setLoading] = useState(true);

  useEffect(() => {
    // Simulating an API call
    setTimeout(() => {
      setStudents([
        { id: 1, name: "Priya Reddy", email: "priya@example.com", city: "Hyderabad" },
        { id: 2, name: "Ravi Kumar", email: "ravi@example.com", city: "Vijayawada" },
        { id: 3, name: "Anjali Sharma", email: "anjali@example.com", city: "Guntur" },
      ]);
      setLoading(false);
    }, 1000);
  }, []); // ← empty array = run once when component mounts

  if (loading) return <p>Loading students...</p>;

  return (
    <div style={{ maxWidth: "600px", margin: "40px auto", padding: "0 16px" }}>
      <h1>Student List ({students.length})</h1>
      {students.map((student) => (
        <StudentCard key={student.id} {...student} />
      ))}
    </div>
  );
}

The [] dependency array controls when useEffect runs:

  • [] — once, on mount
  • [value] — whenever value changes
  • No array — every render (rarely what you want)

Step 7 — Add a Form to Add Students

import { useState, useEffect } from "react";
import StudentCard from "./StudentCard";

function App() {
  const [students, setStudents] = useState([]);
  const [name, setName] = useState("");
  const [email, setEmail] = useState("");

  useEffect(() => {
    setStudents([
      { id: 1, name: "Priya Reddy", email: "priya@example.com", city: "Hyderabad" },
    ]);
  }, []);

  function handleSubmit(e) {
    e.preventDefault();
    if (!name || !email) return;

    const newStudent = { id: Date.now(), name, email, city: "Hyderabad" };
    setStudents([...students, newStudent]); // add to array — never mutate directly
    setName("");
    setEmail("");
  }

  return (
    <div style={{ maxWidth: "600px", margin: "40px auto", padding: "0 16px" }}>
      <h1>Student List ({students.length})</h1>

      <form onSubmit={handleSubmit} style={{ marginBottom: "24px" }}>
        <input
          type="text"
          placeholder="Name"
          value={name}
          onChange={(e) => setName(e.target.value)}
          style={{ display: "block", marginBottom: "8px", padding: "8px", width: "100%" }}
        />
        <input
          type="email"
          placeholder="Email"
          value={email}
          onChange={(e) => setEmail(e.target.value)}
          style={{ display: "block", marginBottom: "8px", padding: "8px", width: "100%" }}
        />
        <button type="submit">Add Student</button>
      </form>

      {students.map((student) => (
        <StudentCard key={student.id} {...student} />
      ))}
    </div>
  );
}

Controlled inputs — React controls the input value through state. Every keystroke updates state, state updates the input. This gives you full control over form data.

What to Learn Next

You now understand the three core concepts of React:

  1. Components — reusable UI pieces
  2. Props — data flowing parent to child
  3. State + Hooks — data that changes over time

Next steps:

  • React Router — navigate between pages in a single-page app
  • Fetch real data — replace setTimeout with fetch('/api/students') from your Spring Boot API
  • Error handling — show error messages when API calls fail
  • TypeScript — add types to your components

In CodeBegun's Java Full Stack program, you build React apps that connect to real Spring Boot APIs — not simulated data. View the full curriculum → or WhatsApp us to join the next batch.

Share:LinkedInFacebookWhatsApp
Siva Prasad Galaba
Staff Engineer at Crunchyroll | Founder, CodeBegun

Founder of CodeBegun. 15+ years building Java systems at companies like Crunchyroll. Teaching the next generation to code the way the industry actually works.

← Back to all posts
Chat with us