React components useprops to communicate with each other. Every parent component can pass some information to its child components by giving them props. Props might remind you of HTML attributes, but you can pass any JavaScript value through them, including objects, arrays, and functions.
You will learn
- How to pass props to a component
- How to read props from a component
- How to specify default values for props
- How to pass some JSX to a component
- How props change over time
Familiar props
Props are the information that you pass to a JSX tag. For example,className,src,alt,width, andheight are some of the props you can pass to an<img>:
functionAvatar(){return(<imgclassName="avatar"src="https://i.imgur.com/1bX5QH6.jpg"alt="Lin Lanying"width={100}height={100}/>);}exportdefaultfunctionProfile(){return(<Avatar/>);}
The props you can pass to an<img> tag are predefined (ReactDOM conforms tothe HTML standard). But you can pass any props toyour own components, such as<Avatar>, to customize them. Here’s how!
Passing props to a component
In this code, theProfile component isn’t passing any props to its child component,Avatar:
exportdefaultfunctionProfile(){
return(
<Avatar/>
);
}You can giveAvatar some props in two steps.
Step 1: Pass props to the child component
First, pass some props toAvatar. For example, let’s pass two props:person (an object), andsize (a number):
exportdefaultfunctionProfile(){
return(
<Avatar
person={{name:'Lin Lanying',imageId:'1bX5QH6'}}
size={100}
/>
);
}Note
If double curly braces afterperson= confuse you, recallthey’re merely an object inside the JSX curlies.
Now you can read these props inside theAvatar component.
Step 2: Read props inside the child component
You can read these props by listing their namesperson, size separated by the commas inside({ and}) directly afterfunction Avatar. This lets you use them inside theAvatar code, like you would with a variable.
functionAvatar({person,size}){
// person and size are available here
}Add some logic toAvatar that uses theperson andsize props for rendering, and you’re done.
Now you can configureAvatar to render in many different ways with different props. Try tweaking the values!
import{getImageUrl}from'./utils.js';functionAvatar({person,size}){return(<imgclassName="avatar"src={getImageUrl(person)}alt={person.name}width={size}height={size}/>);}exportdefaultfunctionProfile(){return(<div><Avatarsize={100}person={{name:'Katsuko Saruhashi',imageId:'YfeOqp2'}}/><Avatarsize={80}person={{name:'Aklilu Lemma',imageId:'OKS67lh'}}/><Avatarsize={50}person={{name:'Lin Lanying',imageId:'1bX5QH6'}}/></div>);}
Props let you think about parent and child components independently. For example, you can change theperson or thesize props insideProfile without having to think about howAvatar uses them. Similarly, you can change how theAvatar uses these props, without looking at theProfile.
You can think of props like “knobs” that you can adjust. They serve the same role as arguments serve for functions—in fact, propsare the only argument to your component! React component functions accept a single argument, aprops object:
functionAvatar(props){
letperson =props.person;
letsize =props.size;
// ...
}Usually you don’t need the wholeprops object itself, so you destructure it into individual props.
Pitfall
Don’t miss the pair of{ and} curlies inside of( and) when declaring props:
functionAvatar({person,size}){
// ...
}This syntax is called“destructuring” and is equivalent to reading properties from a function parameter:
functionAvatar(props){
letperson =props.person;
letsize =props.size;
// ...
}Specifying a default value for a prop
If you want to give a prop a default value to fall back on when no value is specified, you can do it with the destructuring by putting= and the default value right after the parameter:
functionAvatar({person,size =100}){
// ...
}Now, if<Avatar person={...} /> is rendered with nosize prop, thesize will be set to100.
The default value is only used if thesize prop is missing or if you passsize={undefined}. But if you passsize={null} orsize={0}, the default value willnot be used.
Forwarding props with the JSX spread syntax
Sometimes, passing props gets very repetitive:
functionProfile({person,size,isSepia,thickBorder}){
return(
<divclassName="card">
<Avatar
person={person}
size={size}
isSepia={isSepia}
thickBorder={thickBorder}
/>
</div>
);
}There’s nothing wrong with repetitive code—it can be more legible. But at times you may value conciseness. Some components forward all of their props to their children, like how thisProfile does withAvatar. Because they don’t use any of their props directly, it can make sense to use a more concise “spread” syntax:
functionProfile(props){
return(
<divclassName="card">
<Avatar{...props}/>
</div>
);
}This forwards all ofProfile’s props to theAvatar without listing each of their names.
Use spread syntax with restraint. If you’re using it in every other component, something is wrong. Often, it indicates that you should split your components and pass children as JSX. More on that next!
Passing JSX as children
It is common to nest built-in browser tags:
<div>
<img/>
</div>Sometimes you’ll want to nest your own components the same way:
<Card>
<Avatar/>
</Card>When you nest content inside a JSX tag, the parent component will receive that content in a prop calledchildren. For example, theCard component below will receive achildren prop set to<Avatar /> and render it in a wrapper div:
importAvatarfrom'./Avatar.js';functionCard({children}){return(<divclassName="card">{children}</div>);}exportdefaultfunctionProfile(){return(<Card><Avatarsize={100}person={{name:'Katsuko Saruhashi',imageId:'YfeOqp2'}}/></Card>);}
Try replacing the<Avatar> inside<Card> with some text to see how theCard component can wrap any nested content. It doesn’t need to “know” what’s being rendered inside of it. You will see this flexible pattern in many places.
You can think of a component with achildren prop as having a “hole” that can be “filled in” by its parent components with arbitrary JSX. You will often use thechildren prop for visual wrappers: panels, grids, etc.

Illustrated byRachel Lee Nabors
How props change over time
TheClock component below receives two props from its parent component:color andtime. (The parent component’s code is omitted because it usesstate, which we won’t dive into just yet.)
Try changing the color in the select box below:
exportdefaultfunctionClock({color,time}){return(<h1style={{color:color}}>{time}</h1>);}
This example illustrates thata component may receive different props over time. Props are not always static! Here, thetime prop changes every second, and thecolor prop changes when you select another color. Props reflect a component’s data at any point in time, rather than only in the beginning.
However, props areimmutable—a term from computer science meaning “unchangeable”. When a component needs to change its props (for example, in response to a user interaction or new data), it will have to “ask” its parent component to pass itdifferent props—a new object! Its old props will then be cast aside, and eventually the JavaScript engine will reclaim the memory taken by them.
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 inState: A Component’s Memory.
Recap
- To pass props, add them to the JSX, just like you would with HTML attributes.
- To read props, use the
function Avatar({ person, size })destructuring syntax. - You can specify a default value like
size = 100, which is used for missing andundefinedprops. - You can forward all props with
<Avatar {...props} />JSX spread syntax, but don’t overuse it! - Nested JSX like
<Card><Avatar /></Card>will appear asCardcomponent’schildrenprop. - Props are read-only snapshots in time: every render receives a new version of props.
- You can’t change props. When you need interactivity, you’ll need to set state.
Challenge 1 of 3:Extract a component
ThisGallery component contains some very similar markup for two profiles. Extract aProfile component out of it to reduce the duplication. You’ll need to choose what props to pass to it.
import{getImageUrl}from'./utils.js';exportdefaultfunctionGallery(){return(<div><h1>Notable Scientists</h1><sectionclassName="profile"><h2>Maria Skłodowska-Curie</h2><imgclassName="avatar"src={getImageUrl('szV5sdG')}alt="Maria Skłodowska-Curie"width={70}height={70}/><ul><li><b>Profession:</b> physicist and chemist</li><li><b>Awards: 4</b> (Nobel Prize in Physics, Nobel Prize in Chemistry, Davy Medal, Matteucci Medal)</li><li><b>Discovered:</b> polonium (chemical element)</li></ul></section><sectionclassName="profile"><h2>Katsuko Saruhashi</h2><imgclassName="avatar"src={getImageUrl('YfeOqp2')}alt="Katsuko Saruhashi"width={70}height={70}/><ul><li><b>Profession:</b> geochemist</li><li><b>Awards: 2</b> (Miyake Prize for geochemistry, Tanaka Prize)</li><li><b>Discovered:</b> a method for measuring carbon dioxide in seawater</li></ul></section></div>);}