React & Next.js: Beginner's Blog Tutorial
React & Next.js

React & Next.js: Beginner's Blog Tutorial

6 August 20266 min read1110 words
Tags#react#nextjs#components#routing

React is a JavaScript library for building user interfaces out of small, reusable components; Next.js is a framework that wraps React with routing, a build pipeline, and server features. This tutorial takes you through your first components, then props and state, then a minimal Next.js app with two pages. By the end you will understand the three core React ideas and know when plain React is enough and when Next.js earns its place.

What you need before starting

You need Node.js installed (an LTS version such as Node.js 24 is a safe choice; check with node -v), a terminal, and an editor. You should also be comfortable with basic JavaScript: functions, objects, arrays, and arrow functions. If those are shaky, work through a JavaScript primer first; React makes far more sense when the JavaScript underneath it is familiar.

Step 1: Understand components

A React component is a JavaScript function that returns markup. That is the whole idea. The markup syntax is called JSX: it looks like HTML inside JavaScript, and the build tooling turns it into ordinary function calls.

function Welcome() {
  return <h2>Hello from React</h2>;
}

Components compose: a page is a component that renders smaller components, which render smaller ones still. You use a component like a tag:

function App() {
  return (
    <main>
      <Welcome />
      <Welcome />
    </main>
  );
}

Two JSX rules trip up beginners. A component must return a single enclosing element (wrap siblings in a parent tag or an empty <>...</> fragment), and some attributes have different names than in HTML: className instead of class, htmlFor instead of for. Component names must start with a capital letter, which is how React tells your components apart from built-in tags.

Step 2: Pass data with props

Hard-coded components are not reusable. Props are the inputs you pass to a component, and they arrive as a single object argument:

function Greeting({ name, role }) {
  return (
    <p>
      Hello {name}, you are logged in as <strong>{role}</strong>.
    </p>
  );
}

function App() {
  return (
    <main>
      <Greeting name="Ada" role="admin" />
      <Greeting name="Sam" role="viewer" />
    </main>
  );
}

The curly braces switch from markup back into JavaScript, so {name} inserts the prop value. Props flow one way, from parent to child, and a component must never modify its own props. Treat them as read-only inputs; if a value needs to change over time, that is what state is for.

Step 3: Make it interactive with state

State is data a component owns and can change, and changing it is what makes React re-render. The useState hook gives you a value and a function to update it:

import { useState } from "react";

function Counter() {
  const [count, setCount] = useState(0);

  return (
    <button onClick={() => setCount(count + 1)}>
      Clicked {count} times
    </button>
  );
}

Read this carefully, because it is the mental model for everything that follows: you never touch the page directly. You call setCount, React re-runs the component function with the new value, and the button text updates because the returned markup is different. Assigning to count directly does nothing visible; only the setter triggers a re-render. Each rendered Counter keeps its own independent state.

Props and state together cover most day-to-day React: parents own state, pass it down as props, and pass down callback functions so children can request changes.

Step 4: Create a minimal Next.js app

You could wire React up yourself, but a framework saves you the plumbing, and the React team itself recommends starting with one. Create a Next.js project with the standard command:

npx create-next-app@latest my-app

The installer asks a few questions; for a first project, accepting the defaults (TypeScript, App Router, and so on) is fine, and you can answer "No" to TypeScript if you would rather stay in plain JavaScript. Then start the development server:

cd my-app
npm run dev

Open http://localhost:3000 in your browser and you will see the starter page. Leave the server running; it reloads automatically when you save a file.

The file that renders the home page is app/page.js (or page.tsx with TypeScript). Replace its contents with your own component:

export default function Home() {
  return (
    <main>
      <h2>My first Next.js page</h2>
      <p>Rendered by a React component.</p>
    </main>
  );
}

Save, and the browser updates. The export default matters: Next.js looks for the default export of each page file.

Step 5: Add a second page with file-based routing

Next.js maps folders to URLs. There is no router configuration file; the directory structure is the routing table. To create an /about page, make a folder and a page file:

app/
  page.js          →  /
  about/
    page.js        →  /about

Put a component in app/about/page.js:

import Link from "next/link";

export default function About() {
  return (
    <main>
      <h2>About this site</h2>
      <p>Built while learning Next.js.</p>
      <Link href="/">Back home</Link>
    </main>
  );
}

Visit http://localhost:3000/about and it is there. The Link component navigates without a full page reload; use it instead of a plain <a> for internal links. Nested folders create nested routes, and a folder name in square brackets, such as app/posts/[id]/page.js, creates a dynamic route where id comes from the URL.

One thing will bite you early: components in the App Router are server components by default, and hooks like useState do not work in them. When a component needs state or event handlers, put the line "use client"; at the very top of its file. If you see an error mentioning that useState only works in a client component, this is the fix.

When to reach for Next.js, and when not to

Use Next.js when you are building a website or application with multiple pages, when search engines need to read your content (it renders pages on the server, so crawlers get real HTML), or when you want routing, image optimization, and API endpoints without assembling them yourself.

Plain React with a bundler like Vite is a reasonable choice for an internal tool or dashboard that lives behind a login, where SEO is irrelevant and a single page is enough. And if your project is mostly static content with a sprinkle of interactivity, plain HTML with a little JavaScript may beat both; not every site needs a framework. The honest trade-off: Next.js adds concepts to learn (server versus client components above all) in exchange for infrastructure you would otherwise build badly yourself. For most sites that will grow, that trade is worth it.

Where to go next

Stuck on a step? Write to the desk and we will get you unstuck.

Comments

No comments yet. Be the first to share your thoughts.

React & Next.js: First Components to a Working App