Skip to content

Quick Start

Fresh

Creating and Nesting Components

React apps are built from components. A component is a JavaScript function that returns markup.

jsx
function MyButton() {
  return (
    <button>Click me</button>
  );
}

export default function MyApp() {
  return (
    <div>
      <h1>Welcome to my app</h1>
      <MyButton />
    </div>
  );
}

Component names must start with a capital letter. HTML tags must be lowercase.

Writing Markup with JSX

JSX is stricter than HTML:

  • Close all tags (<br />, <img />)
  • A component can only return one root element (wrap in <div> or <>...</>)
  • Use className instead of class
  • Use camelCase for attributes (onClick, tabIndex)
jsx
function AboutPage() {
  return (
    <>
      <h1>About</h1>
      <p>Hello there.<br />How do you do?</p>
    </>
  );
}

Displaying Data

Use curly braces to embed JavaScript expressions in JSX:

jsx
function UserProfile({ user }) {
  return (
    <div>
      <h1>{user.name}</h1>
      <img
        className="avatar"
        src={user.imageUrl}
        alt={'Photo of ' + user.name}
        style={{
          width: user.imageSize,
          height: user.imageSize
        }}
      />
    </div>
  );
}

Conditional Rendering

Use JavaScript if statements, ternary operators, or logical &&:

jsx
function Item({ name, isPacked }) {
  return (
    <li className="item">
      {isPacked ? <del>{name}</del> : name}
    </li>
  );
}

Rendering Lists

Use map() to transform arrays into lists of components. Always provide a key prop:

jsx
const products = [
  { title: 'Cabbage', id: 1 },
  { title: 'Garlic', id: 2 },
  { title: 'Apple', id: 3 },
];

function ShoppingList() {
  const listItems = products.map(product =>
    <li key={product.id}>{product.title}</li>
  );
  return <ul>{listItems}</ul>;
}

Key Rules

Keys must be unique among siblings. Don't use array indices as keys if items can be reordered. Keys should come from your data (database IDs, etc.).

Responding to Events

Declare event handler functions inside your components:

jsx
function MyButton() {
  function handleClick() {
    alert('You clicked me!');
  }

  return (
    <button onClick={handleClick}>
      Click me
    </button>
  );
}

Pass the function, don't call it: onClick={handleClick}, not onClick={handleClick()}.

Updating the Screen with State

Import useState from React to add state to a component:

jsx
import { useState } from 'react';

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

  function handleClick() {
    setCount(count + 1);
  }

  return (
    <button onClick={handleClick}>
      Clicked {count} times
    </button>
  );
}

useState returns two things: the current state value and a function to update it. Convention is [something, setSomething].

Each component instance has its own state. If you render <Counter /> twice, each gets independent state.

Using Hooks

Functions starting with use are called Hooks. useState is a built-in Hook. You can find other built-in Hooks in the API reference, or write your own by combining existing ones.

Hook Rules

Hooks can only be called at the top level of your components or your own Hooks. You cannot call Hooks inside conditions, loops, or nested functions.

Sharing Data Between Components

Lift state up to the closest common parent component to share data:

jsx
import { useState } from 'react';

function MyButton({ count, onClick }) {
  return (
    <button onClick={onClick}>
      Clicked {count} times
    </button>
  );
}

export default function MyApp() {
  const [count, setCount] = useState(0);

  function handleClick() {
    setCount(count + 1);
  }

  return (
    <div>
      <h1>Counters that update together</h1>
      <MyButton count={count} onClick={handleClick} />
      <MyButton count={count} onClick={handleClick} />
    </div>
  );
}

This pattern is called "lifting state up." The parent owns the state and passes it down as props.