Skip to content
react

How to pass props to a component in React

Sep 18th, 2021Abhishek EH14 Min Read

What are props?

Consider a function in any programming language. How do we pass values to the function? Using parameters. Props (properties) are similar to parameters. They are used to pass data from one component to another in React. Below is the simplest example on how to pass props:

App.jsx
1const Banner = props => {
2 const name = props.name
3 return <div>Hello {name}</div>
4}
5
6function App() {
7 return (
8 <div>
9 <Banner name="Abhishek" />
10 </div>
11 )
12}
13
14export default App

A couple of things you need to be aware of props are:

  • Props are read-only, they should not be mutated.
  • We cannot pass props from a child component to a parent component. Props always move from top to bottom in the component hierarchy.

Passing functions as Props

We can pass functions as props as well:

1const Banner = props => {
2 const name = props.name
3 return (
4 <div>
5 <p>Hello {name}</p>
6 <button onClick={props.clickHandler}>Click Me</button>
7 </div>
8 )
9}
10
11function App() {
12 const showAlert = () => {
13 alert("Welcome!")
14 }
15 return (
16 <div>
17 <Banner name="Abhishek" clickHandler={showAlert} />
18 </div>
19 )
20}
21
22export default App

As you could see (line 17), the name of the function and the prop need not be the same.

Passing Boolean values

If you specify a prop without any values, it will be treated as a Boolean with value true:

1const Banner = props => {
2 const name = props.name
3 return <div>{props.show && <p>Hello {name}</p>}</div>
4}
5
6function App() {
7 return (
8 <div>
9 <Banner name="Abhishek" show />
10 </div>
11 )
12}
13
14export default App

If you need to pass false, then you need to explicitly mention it like:

<Banner name="Abhishek" show={false} />

Passing a state as a prop

You can pass the parent component state as a prop to the child component:

1import { useState } from "react"
2
3const Banner = props => {
4 const name = props.name
5 return (
6 <div>
7 <p>
8 {props.greeting} {name}
9 </p>
10 </div>
11 )
12}
13
14function App() {
15 const [greeting, setGreeting] = useState("Hello")
16 return (
17 <div>
18 <Banner name="Abhishek" greeting={greeting} />
19 </div>
20 )
21}
22
23export default App

Also, you can modify the parent state by passing a function to the child component as follows

1import { useState } from "react"
2
3const Banner = props => {
4 const name = props.name
5 return (
6 <div>
7 <p>
8 {props.greeting} {name}
9 </p>
10 <button onClick={props.changeGreeting}>Change greeting</button>
11 </div>
12 )
13}
14
15function App() {
16 const [greeting, setGreeting] = useState("Hello")
17
18 const changeGreeting = () => {
19 setGreeting("Howdy")
20 }
21 return (
22 <div>
23 <Banner
24 name="Abhishek"
25 greeting={greeting}
26 changeGreeting={changeGreeting}
27 />
28 </div>
29 )
30}
31
32export default App

Here we are passing the changeGreeting function as a prop to the Banner component, and calling it from the Banner component when the button is clicked. Inside the changeGreeting function, we are modifying the state to 'Howdy'.

Passing objects as Props

Consider the following example:

1const UserCard = props => {
2 const name = props.user.name
3 const role = props.user.role
4 const age = props.user.age
5 const profilePic = props.user.profilePic
6 return (
7 <div>
8 <p>Name: {name}</p>
9 <p>Role: {role}</p>
10 <p>Age: {age}</p>
11 <img src={profilePic} alt={name} />
12 </div>
13 )
14}
15
16function App() {
17 const user = {
18 name: "Abhishek",
19 role: "Software Engineer",
20 age: 27,
21 profilePic: "image.jpg",
22 }
23
24 return (
25 <div>
26 <UserCard user={user} />
27 </div>
28 )
29}
30
31export default App

Here we are passing an object to the child component and accessing it like props.user.name. So every time we need to access a property, we need to dig through props.user. This can be avoided by passing them as individual props as shown below:

1const UserCard = props => {
2 const name = props.name
3 const role = props.role
4 const age = props.age
5 const profilePic = props.profilePic
6 return (
7 <div>
8 <p>Name: {name}</p>
9 <p>Role: {role}</p>
10 <p>Age: {age}</p>
11 <img src={profilePic} alt={name} />
12 </div>
13 )
14}
15
16function App() {
17 const user = {
18 name: "Abhishek",
19 role: "Software Engineer",
20 age: 27,
21 profilePic: "image.jpg",
22 }
23
24 return (
25 <div>
26 <UserCard
27 name={user.name}
28 role={user.role}
29 age={user.age}
30 profilePic={user.profilePic}
31 />
32 </div>
33 )
34}
35
36export default App

Still we haven't solved the need to write user. for accessing every prop. We just elevated it to parent component. This syntax can be simplified further using Javascript spread operator

1const UserCard = props => {
2 const name = props.name
3 const role = props.role
4 const age = props.age
5 const profilePic = props.profilePic
6 return (
7 <div>
8 <p>Name: {name}</p>
9 <p>Role: {role}</p>
10 <p>Age: {age}</p>
11 <img src={profilePic} alt={name} />
12 </div>
13 )
14}
15
16function App() {
17 const user = {
18 name: "Abhishek",
19 role: "Software Engineer",
20 age: 27,
21 profilePic: "image.jpg",
22 }
23
24 return (
25 <div>
26 <UserCard {...user} />
27 </div>
28 )
29}
30
31export default App

The only change is in line number 26, where instead of passing individual props, we have just passed {...props}.

Destructuring props

If you see the above example, in the child component, we are using props.name, props.age etc for accessing the props. Can we simplify this further? Yes, we can.

1const UserCard = ({ name, role, age, profilePic }) => {
2 return (
3 <div>
4 <p>Name: {name}</p>
5 <p>Role: {role}</p>
6 <p>Age: {age}</p>
7 <img src={profilePic} alt={name} />
8 </div>
9 )
10}
11
12function App() {
13 const user = {
14 name: "Abhishek",
15 role: "Software Engineer",
16 age: 27,
17 profilePic: "image.jpg",
18 }
19
20 return (
21 <div>
22 <UserCard {...user} />
23 </div>
24 )
25}
26
27export default App

As you may observe, we have used JavaScript destructing to access the props directly.

These are just different ways to pass an object to the child component. There is no such thing as the best practice. You may use a style of your choice.

Default props

What if the parent component misses passing a prop? How to make sure our code does not break and there is always a fallback value? We can use default props for that.

Default props can be set using different ways.

Using Short circuit evaluation

We can use the logical OR operator to set a default name as shown below:

1const Banner = props => {
2 const name = props.name || "user"
3 return <div>Hello {name}</div>
4}
5
6function App() {
7 return (
8 <div>
9 <Banner />
10 </div>
11 )
12}
13
14export default App

Using default parameters

We can also specify a default parameter while destructing the props:

1const Banner = ({ name = "user" }) => {
2 return <div>Hello {name}</div>
3}
4
5function App() {
6 return (
7 <div>
8 <Banner />
9 </div>
10 )
11}
12
13export default App

Using defaultProps

There is another way to explicitly specify the default props in React. This is the most recommended approach:

1const Banner = ({ name }) => {
2 return <div>Hello {name}</div>
3}
4
5function App() {
6 return (
7 <div>
8 <Banner />
9 </div>
10 )
11}
12
13Banner.defaultProps = {
14 name: "user",
15}
16
17export default App

Also, you can validate the type of the props using prop-types

Renaming props

If you would like to change the name of the prop, then you can do so as shown below:

1const UserCard = ({ name, role: occupation }) => {
2 return (
3 <div>
4 <p>Name: {name}</p>
5 <p>Occupation: {occupation}</p>
6 </div>
7 )
8}
9
10function App() {
11 return (
12 <div>
13 <UserCard name="Abhi" role="Software Engineer" />
14 </div>
15 )
16}
17
18export default App

Here we are passing a prop called role from the parent component, which we are renaming to occupation in the child component.

Passing components as children

We can pass a component to another component by wrapping it within the parent component as shown below:

1const UserCard = ({ name, children }) => {
2 return (
3 <div>
4 <p>Name: {name}</p>
5 {children}
6 </div>
7 )
8}
9
10const UserIcon = ({ profilePic }) => {
11 return <img src={profilePic} alt="profile" />
12}
13
14function App() {
15 return (
16 <div>
17 <UserCard name="Abhi">
18 <UserIcon profilePic="image.jpg" />
19 </UserCard>
20 </div>
21 )
22}
23
24export default App

As you may see, we can access the passed component using children prop.

An alternate way to pass a component to the child is using a named prop as shown below:

1const UserCard = ({ name, icon }) => {
2 return (
3 <div>
4 <p>Name: {name}</p>
5 {icon}
6 </div>
7 )
8}
9
10const UserIcon = ({ profilePic }) => {
11 return <img src={profilePic} alt="profile" />
12}
13
14function App() {
15 return (
16 <div>
17 <UserCard
18 name="Abhi"
19 icon={<UserIcon profilePic="image.jpg" />}
20 ></UserCard>
21 </div>
22 )
23}
24
25export default App

Hope you have liked the article and have a clear understanding of different ways of passing props in React. Do let me know in the comments below if you have any questions.

Do follow me on twitter where I post developer insights more often!

Leave a Comment

© 2021 CodingDeft.Com