Appearance
Quick Start
FreshCreating 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
classNameinstead ofclass - 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.