Skip to main content
React is a JavaScript library used to create interactive user interfaces. Created by Facebook/Meta, it’s the industry standard for frontend development.

What is React?

React shines in applications with many possible user interactions — like Instagram, YouTube, Netflix, Spotify, and LinkedIn, all of which use React.

Web

React for web applications

Mobile

React Native for iOS and Android

Desktop

Electron for desktop apps
Learn React once and use it on any platform.

Setting Up with Vite

CommandDescription
node -vCheck if Node is installed.
npm installInstall project dependencies.
npm install -g viteInstall Vite globally.
npm create vite@latest .Create Vite project in current folder.
npm run devRun the Vite project.
The dot . in the command creates the project inside the current folder without creating a subfolder.

Project Structure

Understanding the file structure of a React project is essential. Here are the key files you’ll work with:
Standard configuration file for any Node.js project. It contains:
  • Scripts: Available commands like dev, build, etc.
  • Dependencies: Packages required for the project to run
  • devDependencies: Development-only packages
When you run npm install, npm reads this file and installs everything listed.
package.json
{
  "scripts": {
    "dev": "vite",
    "build": "vite build"
  },
  "dependencies": {
    "react": "^18.0.0",
    "react-dom": "^18.0.0"
  }
}
The only HTML file in the application. It serves as a shell with no real content.It contains a <div id="root"></div> where React will inject the entire application via JavaScript. It also loads main.jsx, which is React’s entry point.
index.html
<body>
  <div id="root"></div>
  <!-- empty, React fills it here -->

  <script type="module" src="/src/main.jsx"></script>
</body>
The entry point of the React application. Responsible for rendering the root component (App) inside the div#root from the HTML.This is also where you configure React Router (RouterProvider) when used. You rarely need to edit this file in day-to-day development.
src/main.jsx
import React from 'react'
import ReactDOM from 'react-dom/client'
import App from './App.jsx'

ReactDOM
  .createRoot(document.getElementById('root'))
  .render(<App />)
The root component of the application — the first component React renders.Functions as the central point where you organize other components and manage main application states. It’s common to keep global states here and pass data to children via props.
src/App.jsx
import { useState } from 'react'
import Tasks from './components/Tasks'

function App() {
  const [tasks, setTasks] = useState([])

  return <Tasks tasks={tasks} />
}

export default App
There’s no mandatory structure, but the most common convention separates code into folders inside src/:
  • components/ — Reusable UI pieces (buttons, cards, lists, etc.)
  • pages/ — Components that represent a full route/page
Component files always use the .jsx extension and PascalCase naming (e.g., AddTask.jsx, TaskPage.jsx).
📁 src/
  📁 components/
    AddTask.jsx
    Tasks.jsx
  📁 pages/
    TaskPage.jsx
  App.jsx
  main.jsx
  index.css
index.html
package.json

Single Page Application (SPA)

React generates a SPA — the application’s HTML is practically empty. Content is dynamically inserted via JavaScript.Instead of having one HTML file per page, React manages all pages via JavaScript with just one base HTML.
If you disable JavaScript in the browser, you won’t see anything in a React SPA.

Components

In React, the application is divided into components — think of them as LEGO pieces that combine to form complete pages. Each component is a JavaScript function that returns JSX. By convention, use PascalCase to name them (e.g., AddTask, TaskList).
src/components/MyComponent.jsx
function MyComponent() {
  return (
    <div>
      <h1>Hello World</h1>
    </div>
  );
}

export default MyComponent;
Component files use the .jsx extension, created inside the src/components/ folder.
The return of a component can only have one root element. Use a <div> or a Fragment (<></>) to wrap multiple elements.

JSX

JSX is a special syntax: HTML mixed with JavaScript.
To use JavaScript inside JSX, wrap it with {} (curly braces).
const name = "Felipe";

return (
  <div className="container">
    <h1>Hello, {name}</h1>
    <button onClick={() => alert('clicked!')}>
      Click here
    </button>
  </div>
);

State with useState

State is a special React variable: when you change the state, the interface automatically updates (re-render). It’s created with the useState Hook, imported from React. Returns an array with [value, update function].
import { useState } from 'react';

function App() {
  const [message, setMessage] = useState('Hello World');

  return (
    <div>
      <h1>{message}</h1>
      <button onClick={() => setMessage('Clicked!')}>
        Change
      </button>
    </div>
  );
}
Use state whenever you want to react to user interactions — that’s where the name “React” comes from.

Props

Props are the way to pass data from a parent component to a child component.
<Tasks tasks={taskList} />
Everything you pass as an attribute becomes available inside props.attributeName.

Side Effects with useEffect

The useEffect executes a function whenever a value in the dependency list (second parameter) changes.
// Runs when 'tasks' changes
useEffect(() => {
  localStorage.setItem(
    'tasks',
    JSON.stringify(tasks)
  );
}, [tasks]);
Don’t use async directly in the useEffect function. Create an async function inside and call it.

localStorage Persistence

The localStorage persists data in the browser even after closing the tab or browser.
// Initialize state with data from storage
const [tasks, setTasks] = useState(
  JSON.parse(localStorage.getItem('tasks')) || []
);

// Save to storage when tasks change
useEffect(() => {
  localStorage.setItem('tasks', JSON.stringify(tasks));
}, [tasks]);
Stores only strings, so use JSON.stringify() to save and JSON.parse() to retrieve.

Routing with React Router Dom

React Router manages routes (pages) in an SPA using JavaScript, without multiple HTMLs. Install: npm install react-router-dom@6.26.1 Create a src/pages/ folder for page components. Pages are common components — the name is just semantic.
Hook / ComponentUse
createBrowserRouterCreates the router with the list of routes (path + element).
RouterProviderComponent that wraps the application and injects the router.
useNavigate()Hook to navigate between routes. navigate('/route') or navigate(-1) to go back.
useSearchParams()Hook to read query params from URL. E.g., ?title=foo&desc=bar.
When passing functions to onClick, never call them directly (onClick={func()}). Pass the reference (onClick={func}) or use an arrow function (onClick={() => func(param)}).

Consuming APIs with fetch

The most common flow for APIs in React:
1

Component is mounted

Component renders for the first time
2

useEffect calls the API

Effect with empty dependencies [] triggers
3

Data saved in state

setState updates the component state
4

Interface updated

Component re-renders with new data
useEffect(() => {
  async function fetchTasks() {
    const response = await fetch(
      'https://jsonplaceholder.typicode.com/todos?_limit=10',
      { method: 'GET' }
    );
    const data = await response.json();
    setTasks(data);
  }
  fetchTasks();
}, []);

Next Steps

Data Fetching

React Query (most popular) or SWR for managing API calls.

Forms

React Hook Form + Zod for complex form validation.

Global State

Context API + useReducer → then Zustand and Redux.

Testing

Jest / Vitest + React Testing Library + Cypress (e2e).

React on Server

Server Components + Next.js (market standard) or Remix.

GraphQL

Apollo Client for consuming GraphQL APIs in React.