Lec 2
Lec 2
1
A library for web and native user interfaces
Create user interfaces from components
◦ React lets you build user interfaces out of individual pieces of
code called components
◦ Create your own React components
◦ Then combine them into entire pages and apps
Write components with code and markup
◦ React components are JavaScript functions
◦ This markup syntax is called JSX, which is a JavaScript syntax
extension popularized by React
◦ JSX is HTML-like syntax that can compile down to pure
JavaScript
Add interactivity wherever you need it
◦ React components receive data and return what should appear on the
screen
◦ You can pass them new data in response to an interaction, like when the
user types into an input
◦ React will then update the screen to match the new data
2
React apps are made out of components
A component is a piece of the UI that has its own
logic and appearance
A component can be as small as a button, or as
large as an entire page
React components are JavaScript functions that
return markup:
function MyButton() {
return (
<button>I'm a button</button>
);
}
3
Now that you’ve declared MyButton, you can nest
it into another component:
export default function MyApp() {
return (
<div>
<h1>Welcome to my app</h1>
<MyButton />
</div>
);
}
4
JSX is stricter than HTML
Your component can’t return multiple JSX tags
You have to wrap them into a shared parent, like
a <div>...</div> or an empty <>...</> wrapper:
function AboutPage() {
return (
<>
<h1>About</h1>
<p>Hello there.<br />How do you do?</p>
</>
);
}
5
In React, you specify a CSS class with
“className”
It works the same way as the HTML class
attribute:
<img className="avatar" />
/* In your CSS */
.avatar {
border-radius: 50%;
}
6
JSX lets you put markup into JavaScript
Curly braces let you “escape back” into JavaScript so that
you can embed some variable from your code and display
it to the user
For example, this will display user.name:
return (
<h1>
{user.name}
</h1>
);
You can also “escape into JavaScript” from JSX attributes:
return (
<img
className="avatar"
src={user.imageUrl}
/>
);
7
const user = {
name: 'Hedy Lamarr',
imageUrl: 'https://i.imgur.com/yXOvdOSs.jpg',
imageSize: 90,
};
export default function Profile() {
return (
<>
<h1>{user.name}</h1>
<img className="avatar“
src={user.imageUrl}
alt={'Photo of ' + user.name}
style={{
width: user.imageSize,
height: user.imageSize
}}
/>
</>
);
}
8
In React, there is no special syntax for writing
conditions
Instead, you’ll use the same techniques as you
use when writing regular JavaScript code:
<div>
{isLoggedIn ? (
<AdminPanel />
):(
<LoginForm />
)}
</div>
When you don’t need the else branch:
<div>
{isLoggedIn && <AdminPanel />}
</div>
9
You will rely on JavaScript features like the array
map() function to render lists of components:
const products = [
{ title: 'Cabbage', id: 1 },
{ title: 'Garlic', id: 2 },
{ title: 'Apple', id: 3 },
];
const listItems = products.map(product =>
<li key={product.id}>
{product.title}
</li>
);
return (
<ul>{listItems}</ul>
);
10
You can respond to events by declaring event
handler functions inside your components:
function MyButton() {
function handleClick() {
alert('You clicked me!');
}
return (
<button onClick={handleClick}>
Click me
</button>
);
}
11
12
13
Often, you’ll want your component to
“remember” some information and display it
For example, maybe you want to count the
number of times a button is clicked
To do this, add state to your component
First, import useState from React:
import { useState } from 'react';
Now you can declare a state variable inside your
component:
function MyButton() {
const [count, setCount] = useState(0);
// ...
14
You’ll get two things from useState:
◦ The current state (count)
◦ The function that lets you update it (setCount)
◦ You can give them any names, but the convention is to write
[something, setSomething]
function MyButton() {
const [count, setCount] = useState(0);
function handleClick() {
setCount(count + 1);
}
return (
<button onClick={handleClick}>
Clicked {count} times
</button>
);
}
15
If you render the same component multiple times, each will get its own
state:
import { useState } from 'react';
export default function MyApp() {
return (
<div> <h1>Counters that update separately</h1>
<MyButton />
<MyButton />
</div>
);
}
function MyButton() {
const [count, setCount] = useState(0);
function handleClick() {
setCount(count + 1);
}
return (
<button onClick={handleClick}>
Clicked {count} times
</button>
);
}
16
Functions starting with use are called Hooks
The useState is a built-in Hook provided by React
◦ You can find other built-in Hooks in the API reference:
◦ https://react.dev/reference/react
State Hooks: State lets a component “remember”
information like user input
Context Hooks: Context lets a component receive
information from distant parents without passing it as props
Ref Hooks: Refs let a component hold some information that
isn’t used for rendering
Effect Hooks: Effects let a component connect to and
synchronize with external systems
Hooks are more restrictive than other functions
◦ You can only call Hooks at the top of your components
(or other Hooks)
17
In the previous example, each MyButton had its
own independent count, and when each button
was clicked, only the count for the button clicked
changed
Initially each MyButton’s count state is 0
When MyButton is clicked its count state changed
to 1
18
However, often you’ll need components to share
data and always update together
To make both MyButton components display the
same count and update together:
◦ You need to move the state from the individual buttons
“upwards” to the closest component containing all of
them
19
First, move the state up from MyButton into MyApp
Then, pass the state down from MyApp to each MyButton, together with the
shared click handler
Finally, change MyButton to read the props you have passed from its parent
component:
import { useState } from 'react';
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>
);
}
function MyButton({ count, onClick }) {
return (
<button onClick={onClick}>
Clicked {count} times
</button>
);
}
20