React Docs: Get Started
Table of Contents
Quick Start
React component names must start with a capital letter.
JSX has to be wrapped in a shared parent, e.g. <>...</>
.
className
specifies CSS class.
Curly braces allow an escape back into JavaScript.
Conditionals may be written in long form,
let content; if (isLoggedIn) { content = <AdminPanel />; } else { content = <LoginForm />; } return ( <div> {content} </div> );
using the conditional ?
operator,
<div> {isLoggedIn ? ( <AdminPanel /> ) : ( <LoginForm /> )} </div>
or using the logical &&
syntax.
<div> {isLoggedIn && <AdminPanel />} </div>
React relies on keys for keeping track of elements in a list.
An example of an event handler:
function MyButton() { function handleClick() { alert('You clicked me!'); } return ( <button onClick={handleClick}> Click me </button> ); }
Functions starting with use
are called Hooks.
Tutorial: Tic-Tac-Toe
export
makes a function accessible outside of its file. default
informs
other files that it’s the main function.
import { useState } from "react"; const Square = ({ value, onSquareClick }) => { return ( <button className="square" onClick={onSquareClick}> {value} </button> ); } export default const Board = ({ xIsNext, squares, onPlay }) => { const handleClick = (i) => { if (calculateWinner(squares) || squares[i]) { return; } const nextSquares = squares.slice(); if (xIsNext) { nextSquares[i] = "X"; } else { nextSquares[i] = "O"; } onPlay(nextSquares); } const winner = calculateWinner(squares) let status; if (winner) { status = "Winner: " + winner; } else { status = "Next player: " + (xIsNext ? "X" : "O"); } return ( <> <div className="board-row"> <Square value={squares[0]} onSquareClick={() => handleClick(0)} /> <Square value={squares[1]} onSquareClick={() => handleClick(1)} /> <Square value={squares[2]} onSquareClick={() => handleClick(2)} /> </div> <div className="board-row"> <Square value={squares[3]} onSquareClick={() => handleClick(3)} /> <Square value={squares[4]} onSquareClick={() => handleClick(4)} /> <Square value={squares[5]} onSquareClick={() => handleClick(5)} /> </div> <div className="board-row"> <Square value={squares[6]} onSquareClick={() => handleClick(6)} /> <Square value={squares[7]} onSquareClick={() => handleClick(7)} /> <Square value={squares[8]} onSquareClick={() => handleClick(8)} /> </div> </> ); } export default const Game = () => { const [history, setHistory] = useState([Array(9).fill(null)]); const [currentMove, setCurrentMove] = useState(0); const xisNext = currentMove % 2 === 1; const currentSquares = history[currentMove]; const handlePlay = (nextSquares) => { const nextHistory = [...history.slice(0, currentMove + 1), nextSquares]; setHistory(nextHistory); setCurrentMove(nextHistory.length - 1); } const jumpTo(nextMove) { setCurrentMove(nextMove); } const moves = history.map((squares, move) => { let description; if (move > 0) { description = "Go to move #" + move; } else { description = "Go to game start"; } return ( <li key={move}> <button onClick={() => jumpTo(move)}>{description}</button> </li> ); }); return ( <div className="game"> <div className="game-board"> <Board xIsNext={xIsNext} squares={currentSquares} onPlay={handlePlay} /> </div> <div className="game-info"> <<ol>{moves}</ol> </div> </div> ); } const calculateWinner = (squares) => { const lines = [ [0, 1, 2], [3, 4, 5], [6, 7, 8], [0, 3, 6], [1, 4, 7], [2, 5, 8], [0, 4, 8], [2, 4, 6], ]; for (let i = 0; i < lines.length; i++) { const [a, b, c] = lines[i]; if ( squares[a] && squares[a] === squares[b] && squares[a] === squares[c] ) { return squares[a]; } } return null; }
Extra challenges:
For the current move only, show ‘You are at move #…’ instead of a button.
Rewrite
Board
to use two loops to make the squares instead of hardcoding them.Add a toggle button that lets you sort the moves in either ascending or descending order.
When someone wins, highlight the three squares that caused the wine (and when no one wins, display a message about the result being a draw).
Display the location of each move in the format (col, row) in the move history list.
Thinking in React
Props are like arguments you pass to a function. State is like a component’s memory.
To think in React:
Break the UI into a component hierarchy,
Build a static version in React,
Find the minimal but complete representation of UI state,
Identify where your state should live,
Add inverse data flow.