Skip to main content

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} />;
}
note

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.

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>
);
}

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.

tip

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!

note

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.