4.5 - Passing Props
What are props?
React components use props to communicate with each other.
Props are the information that you pass to a JSX tag, and can be any JavaScript value like object, arrays, or functions. For example, className
, src
, alt
, width
, and height
are some of the props you can pass to an <img>
.
Here is an example:
// Remember to type your props!
interface AvatarProps {
src: string;
alt: string;
width: number;
height: number;
}
function Avatar() {
return (
<img
// Props that you pass to <img>
className="avatar"
src={src}
alt={alt}
width={width}
height={height}
/>
);
}
export default function Profile() {
return <Avatar src="https://Elaine.jpg" alt="Elaine" width={100} height={100} />;
}
While the props you can pass to an <img>
tag are predefined, you can pass any props to your own components to customize them.
Passing props to a component
In this code, the Profile
component isn’t passing any props to its child component, Avatar
:
export default function Profile() {
return <Avatar />;
}
You can give Avatar
some props in two steps.
Step 1: Pass props to the child component
First, pass some props to Avatar
. For example, let’s pass two props: person
(an object), and size
(a number):
export default function Profile() {
return <Avatar person={{ name: "Elaine", imageId: "1" }} size={100} />;
}
Recall that double curly braces after person=
denote that there is an object inside the JSX curlies.
Now you can read these props inside the Avatar
component.
Step 2: Read props inside the child component
You can read these props by listing their names person, size
separated by the commas inside ({
and })
directly after function Avatar
. This lets you use them inside the Avatar
code, like you would with a variable.
function Avatar({ person, size }) {
// person and size are available here
}
Add some logic to Avatar
that uses the person and size props for rendering, and you’re done.
Now you can configure Avatar
to render in many different ways with different props.
- App.js
- util.js
import { getImageUrl } from './utils.js';
function Avatar({ person, size }) {
return (
<img
className="avatar"
src={getImageUrl(person)}
alt={person.name}
width={size}
height={size}
/>
);
}
export default function Profile() {
return (
<div>
<Avatar
size={100}
person={{
name: 'Elaine Shu',
imageId: '1'
}}
/>
<Avatar
size={100}
person={{
name: 'Cady He',
imageId: '2'
}}
/>
</div>
);
}
export function getImageUrl(person, size = 's') {
return (
'https://i.imgur.com/' +
person.imageId +
size +
'.jpg'
);
}
Props let you think about parent and child components independently. For example, you can change the person
or the size
props inside Profile
without having to think about how Avatar
uses them. Similarly, you can change how the Avatar
uses these props, without looking at the Profile
.
You can think of props like function arguments-in fact, React component functions accept a single argument, a props
object:
function Avatar(props) {
let person = props.person;
let size = props.size;
// ...
}
Usually you don’t need the whole props object itself, so you destructure it into individual props.
Don’t miss the pair of {
and }
curlies inside of (
and )
when declaring props:
function Avatar({ person, size }) {
// ...
}
This syntax is called “destructuring” and is equivalent to reading properties from a function parameter:
function Avatar(props) {
let person = props.person;
let size = props.size;
// ...
}
Specifying a default value for a prop
//you can specify a default value right after the parameter with "="
function Avatar({ person, size = 100 }) {
// ...
}
Forwarding props with the JSX spread syntax
Sometimes, passing props gets very repetitive. Some components forward all of their props to their children, like how this Profile does with Avatar. Because they don’t use any of their props directly, it can make sense to use a more concise “spread” syntax:
function Profile({ person, size, isSepia, thickBorder }) {
return (
<div className="card">
<Avatar {...props} /> //is equivalent to:
{/* <Avatar
person={person}
size={size}
isSepia={isSepia}
thickBorder={thickBorder}
/> */}
</div>
);
}
How props change over time
Props reflect a component’s data at any point in time -- meaning it can be updated (for example when there's new data or a user interaction).
For example, a clock can take a time
prop, which changes every second!
Since props are immutable, when a component needs to change its props it will have to “ask” its parent component to pass it new props—a new object!
Don’t try to “change props”. When you need to respond to the user input (like changing the selected color), you will need to “set state”, which you can learn about in Lecture 5.