React Quickstart
This tutorial assumes you’re already familiar with HTML, CSS, and JS. It also assumes you know what a JS framework is for.
Online Setup
Section titled “Online Setup”If you prefer to work online, you can open the React training ground repo on Stackblitz and start coding right away in your browser. You don’t have to run any of the npm commands if you use Stackblitz.
Local Setup
Section titled “Local Setup”If you prefer to work locally, you can follow these steps (you will need Node and npm installed).
First, visit the React training ground repo. Press the green Code button and click Download ZIP. Unzip the file and then open it in your editor. Then, run this command in the terminal to install the packages listed in package.json
.
npm install
Then run this command to start the dev server.
npm run dev
You should see something like this in your terminal.
VITE v6.3.2 ready in 251 ms
➜ Local: http://localhost:5173/ ➜ Network: use --host to expose ➜ press h + enter to show help
Visit localhost:5173 in your browser. The web page should say Hello World.
In your editor, you’ll see several files. However, for now you’ll mainly be working in src/components/HelloWorld.jsx
.
React uses a syntax extension called JSX that lets you mix in HTML-like code with your JavaScript code. It’s described as HTML-like because there are some small differences from HTML. You’ll learn more about them later in this quickstart.
Hello World
Section titled “Hello World”In our file, we have an <h1>
element already added.
function HelloWorld() { return <h1>Hello World</h1>;}
export default HelloWorld;
Task: To make it more personal, change World
to your name.
function HelloWorld() { return <h1>Hello John</h1>;}
export default HelloWorld;
After saving, you should see the browser show your name.
Multiple elements
Section titled “Multiple elements”In React, a component must return a single JSX element. However, you can have multiple elements within a parent element.
Task: Add a <p>
element after the <h1>
element with some placeholder text.
function HelloWorld() { return ( <> <h1>Hello John</h1> <p>Lorem ipsum dolor...</p> </> );}
export default HelloWorld;
Notice that we’ve wrapped our elements in <>
and </>
. This is a React Fragment, which allows us to return multiple elements without adding an extra node to the DOM.
After saving, you should see both elements appear on screen.
App.jsx
Section titled “App.jsx”Before we look at our next topic, open up App.jsx
so you can see how it’s importing HelloWorld.jsx
.
import './App.css';import HelloWorld from './components/HelloWorld';
function App() { return ( <HelloWorld /> );}
export default App;
style attribute
Section titled “style attribute”You can add a style
attribute to an element just like in normal HTML, but in React you pass an object instead of a string.
Task: Add style={{ color: 'red' }}
to the h1 element.
function HelloWorld() { return ( <> <h1 style={{ color: 'red' }}>Hello John</h1> <p>Lorem ipsum dolor...</p> </> );}
export default HelloWorld;
After saving, you should see the <h1>
element turn red in the browser.
You can also create a style object ahead of time instead of putting the object inline.
const myStyle = { color: 'red'}
function HelloWorld() { return ( <> <h1 style={myStyle}>Hello John</h1> <p>Lorem ipsum dolor...</p> </> );}
export default HelloWorld;
External CSS File
Section titled “External CSS File”You typically add styles using external CSS files. Create a CSS file inside src/components
called HelloWorld.css
.
h1 { color: red;}
Task: Delete the inline style
attribute. Create HelloWorld.css
and import it into HelloWorld.jsx
.
import './HelloWorld.css';
function HelloWorld() { return ( <> <h1>Hello John</h1> <p>Lorem ipsum dolor...</p> </> );}
export default HelloWorld;
After saving, you should see that the <h1>
element is still red. Styles imported this way are global by default.
className
Attribute
Section titled “className Attribute”To apply CSS classes, React uses the className
attribute instead of class
(because class
is a reserved keyword in JavaScript).
Task: In HelloWorld.css
, change the h1
selector to a class selector, e.g., .red
. Then, add className="red"
to the <h1>
element in HelloWorld.jsx
.
.red { color: red;}
import './HelloWorld.css';
function HelloWorld() { return ( <> <h1 className="red">Hello John</h1> <p>Lorem ipsum dolor...</p> </> );}
export default HelloWorld;
After saving, the <h1>
element should still be red.
Add a name
prop to the HelloWorld
component.
function HelloWorld({name}) { return <h1>Hello {name}</h1>;}
export default HelloWorld;
Then pass in the name prop to the HelloWorld
component inside App.jsx
.
import './App.css';import HelloWorld from './components/HelloWorld';
function App() { return ( <HelloWorld name="John" /> );}
export default App;
The page should display whatever name you passed in.
References
Add a state variable
Section titled “Add a state variable”For this section, create a new file called Counter.jsx
. Add the following code to it.
function Counter() { return ( <button>Count: 0</button> );}
export default Counter;
Next, make sure to import it into App.jsx
.
import HelloWorld from './components/HelloWorld';import Counter from './components/Counter';
function App() { return ( <Counter /> );}
export default App;
After saving you should see the button appear on screen. It doesn’t do anything yet if you click on it.
Back in Counter.jsx
, import useState
from React and create a state variable called count
. Replace the number 0
with {count}
.
import { useState } from 'react';
function Counter() { const [count, setCount] = useState(0);
return ( <button>Count: {count}</button> );}
export default Counter;
After saving, the button should still look the same. It still doesn’t do anything yet.
References
Make it reactive
Section titled “Make it reactive”Next, add an onClick
handler to the button that increments the count.
import { useState } from 'react';
function Counter() { const [count, setCount] = useState(0);
return ( <button onClick={() => setCount(count + 1)}>Count: {count}</button> );}
export default Counter;
After saving, the number on the button will go up by 1 when you click on it.
References
Use a function
Section titled “Use a function”Create a function called increment()
. Then replace the inline function with a reference to increment
.
import { useState } from 'react';
function Counter() { const [count, setCount] = useState(0);
function increment() { setCount(count + 1); }
return ( <button onClick={increment}>Count: {count}</button> );}
export default Counter;
After saving, the number on the button should still go up by 1 when you click on it.
Conditional
Section titled “Conditional”Let’s learn how to display elements conditionally.
If you only need an if condition, you can use the &&
syntax in the return
statement.
import { useState } from 'react';
function Counter() { const [count, setCount] = useState(0);
function increment() { setCount(count + 1); }
return ( <div> {count > 10 && <h1>Good job!</h1>} <button onClick={increment}>Count: {count}</button> </div> );}
export default Counter;
This will display a heading with the phrase “Good job!” in the browser if the count is larger than 10. Try clicking on the button more than 10 times to test it out.
If you need an if and an else statement you can use a ternary operator in the return
statement.
import { useState } from 'react';
function Counter() { const [count, setCount] = useState(0);
function increment() { setCount(count + 1); }
return ( <div> {count > 10 ? <h1>Good job!</h1> : <h1>Let's get started</h1>} <button onClick={increment}>Count: {count}</button> </div> );}
export default Counter;
This will display a heading with the phrase “Good job!” in the browser if the count is larger than 10. If not, it will display the phrase “Let’s get started”. Try clicking on the button more than 10 times to test it out.
If you need a more complicated conditional structure, you can use an if/else if/else statement outside of the return statement.
import { useState } from 'react';
function Counter() { const [count, setCount] = useState(0);
function increment() { setCount(count + 1); }
let message; if (count > 10) { message = <h1>Good job!</h1>; } else if (count > 5) { message = <h1>Not bad</h1>; } else { message = <h1>Let's get started</h1>; }
return ( <div> {message} <button onClick={increment}>Count: {count}</button> </div> );}
export default Counter;
This will display a heading with the phrase “Good job!” in the browser if the count is larger than 10. If the count is between 5 and 10, it will say “Not bad”. If it’s less than 5, it will say “Let’s get started”. Try clicking on the button more than 10 times to test it out.
References
Binding
Section titled “Binding”Let’s learn about binding. Binding is the technique that’s used to keep the value of an input in sync with a reactive variable.
Let’s reset the Hello World component back to this.
function HelloWorld() { return <h1>Hello World</h1>;}
export default HelloWorld;
Then, add the following code.
import { useState } from 'react';
function HelloWorld() { const [name, setName] = useState('');
return ( <> <input value={name} onChange={e => setName(e.target.value)} /> <h1>Hello {name}</h1> </> );}
export default HelloWorld;
The parts that say value={name}
and onChange={e => setName(e.target.value)}
are how you bind the input to the name variable, which is reactive.
Now the heading will update whenever you type in the input.
For this section, we’re going to create a new file called TodoList.jsx
. Add the following code to it.
import { useState } from 'react';
function TodoList() { const [todos, setTodos] = useState([ { id: crypto.randomUUID(), text: 'Buy groceries' }, { id: crypto.randomUUID(), text: 'Read a book' }, { id: crypto.randomUUID(), text: 'Go for a walk' }, ]);
return ( <> <ul> {todos.map((todo) => ( <li key={todo.id}>{todo.text}</li> ))} </ul> </> );}
export default TodoList;
Next, make sure to import it into App.jsx
.
import HelloWorld from './components/HelloWorld';import Counter from './components/Counter';import TodoList from './components/TodoList';
function App() { return ( <TodoList /> );}
export default App;
References
Add items
Section titled “Add items”Next, add a newItem
state variable, the handleAdd()
function and the <input>
element.
8 collapsed lines
import { useState } from 'react';
function TodoList() { const [todos, setTodos] = useState([ { id: crypto.randomUUID(), text: 'Buy groceries' }, { id: crypto.randomUUID(), text: 'Read a book' }, { id: crypto.randomUUID(), text: 'Go for a walk' }, ]); const [newTodo, setNewTodo] = useState("");
const handleAdd = () => { setTodos([ ...todos, { id: crypto.randomUUID(), text: newTodo } ]); setNewTodo(""); };
return ( <> <input value={newTodo} onChange={(e) => setNewTodo(e.target.value)} /> <button onClick={handleAdd}>Add</button> <ul> {todos.map((todo) => ( <li key={todo.id}>{todo.text}</li> ))} </ul> </> );}
export default TodoList;
After saving, you should be able to add items to the list.
Remove items
Section titled “Remove items”Next, add the handleDelete()
function and the <button>
element.
18 collapsed lines
import { useState } from "react";
function TodoList() { const [todos, setTodos] = useState([ { id: crypto.randomUUID(), text: 'Buy groceries' }, { id: crypto.randomUUID(), text: 'Read a book' }, { id: crypto.randomUUID(), text: 'Go for a walk' }, ]); const [newTodo, setNewTodo] = useState("");
const handleAdd = () => { setTodos([ ...todos, { id: crypto.randomUUID(), text: newTodo } ]); setNewTodo(""); };
const handleDelete = (id) => { setTodos(todos.filter((todo) => todo.id !== id)); };
return ( <> <input value={newTodo} onChange={(e) => setNewTodo(e.target.value)} /> <button onClick={handleAdd}>Add</button> <ul> {todos.map((todo) => ( <li key={todo.id}> {todo.text}{" "} <button onClick={() => handleDelete(todo.id)}> Delete </button> </li> ))} </ul> </> );}
export default TodoList;
After saving, you should be able to delete items from the list.
Filter items
Section titled “Filter items”Next, add the toggleTodo()
function and the <input>
element. Also, add a completed
property to each item in the list of items.
import { useState } from "react";
function TodoList() { const [todos, setTodos] = useState([ { id: crypto.randomUUID(), text: "Buy groceries", completed: false }, { id: crypto.randomUUID(), text: "Read a book", completed: false }, { id: crypto.randomUUID(), text: "Go for a walk", completed: false } ]);14 collapsed lines
const [newTodo, setNewTodo] = useState("");
const handleAdd = () => { setTodos([ ...todos, { id: crypto.randomUUID(), text: newTodo } ]); setNewTodo(""); };
const handleDelete = (id) => { setTodos(todos.filter((todo) => todo.id !== id)); };
const toggleTodo = (id) => { setTodos( todos.map((todo) => todo.id === id ? { ...todo, completed: !todo.completed } : todo ) ); };
return ( <> <input value={newTodo} onChange={(e) => setNewTodo(e.target.value)} /> <button onClick={handleAdd}>Add</button> <ul> {todos.map((todo) => ( <li key={todo.id}> <input type="checkbox" checked={todo.completed} onChange={() => toggleTodo(todo.id)} /> {todo.text}{" "} <button onClick={() => handleDelete(todo.id)}> Delete </button> </li> ))} </ul> </> );}
export default TodoList;
Next, add a hideCompleted
state variable and a filteredItems
variable.
import { useState } from "react";
function TodoList() { const [todos, setTodos] = useState([ { id: crypto.randomUUID(), text: "Buy groceries", completed: false }, { id: crypto.randomUUID(), text: "Read a book", completed: false }, { id: crypto.randomUUID(), text: "Go for a walk", completed: false } ]); const [newTodo, setNewTodo] = useState(""); const [hideCompleted, setHideCompleted] = useState(false);
19 collapsed lines
const handleAdd = () => { setTodos([ ...todos, { id: crypto.randomUUID(), text: newTodo } ]); setNewTodo(""); };
const handleDelete = (id) => { setTodos(todos.filter((todo) => todo.id !== id)); };
const toggleTodo = (id) => { setTodos( todos.map((todo) => todo.id === id ? { ...todo, completed: !todo.completed } : todo ) ); };
const visibleTodos = hideCompleted ? todos.filter((todo) => !todo.completed) : todos;
return ( <> <input value={newTodo} onChange={(e) => setNewTodo(e.target.value)} /> <button onClick={handleAdd}>Add</button> <input type="checkbox" checked={hideCompleted} onChange={() => setHideCompleted(!hideCompleted)} /> <label>Hide Completed</label> <ul> {visibleTodos.map((todo) => ( <li key={todo.id}> <input type="checkbox" checked={todo.completed} onChange={() => toggleTodo(todo.id)} /> {todo.text}{" "} <button onClick={() => handleDelete(todo.id)}> Delete </button> </li> ))} </ul> </> );}
export default TodoList;
After saving, you should be able to hide completed items.
CSS + JS
Section titled “CSS + JS”Let’s learn how to toggle classes in React. For this section, we’re going to use the HelloWorld.css
file we created earlier.
.red { color: red;}
In HelloWorld.jsx
, use a ternary operator with the className
prop to toggle the class. Also, add an onClick
prop with an inline function that toggles the isActive
state variable.
import { useState } from 'react';import './HelloWorld.css';
function HelloWorld() { const [isActive, setIsActive] = useState(true);
return ( <> <h1 className={isActive ? 'red' : ''}>Hello World</h1> <button onClick={() => setIsActive(!isActive)}> Toggle </button> </> );}
AI & Prompting
Section titled “AI & Prompting”React has been out for a while, so you generally don’t need any specific prompts to generate good React code. You should be able to use any major LLM and get good results.