How to pass props to a component in React
Tags: react
Published: 2021-10-22 05:20:47

## 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:

```jsx
const Banner = props => {
  const name = props.name
  return <div>Hello {name}</div>
}

function App() {
  return (
    <div>
      <Banner name="Abhishek" />
    </div>
  )
}

export 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:

```jsx
const Banner = props => {
  const name = props.name
  return (
    <div>
      <p>Hello {name}</p>
      <button onClick={props.clickHandler}>Click Me</button>
    </div>
  )
}

function App() {
  const showAlert = () => {
    alert("Welcome!")
  }
  return (
    <div>
      <Banner name="Abhishek" clickHandler={showAlert} />
    </div>
  )
}

export 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`:

```jsx
const Banner = props => {
  const name = props.name
  return <div>{props.show && <p>Hello {name}</p>}</div>
}

function App() {
  return (
    <div>
      <Banner name="Abhishek" show />
    </div>
  )
}

export 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:

```jsx
import { useState } from "react"

const Banner = props => {
  const name = props.name
  return (
    <div>
      <p>
        {props.greeting} {name}
      </p>
    </div>
  )
}

function App() {
  const [greeting, setGreeting] = useState("Hello")
  return (
    <div>
      <Banner name="Abhishek" greeting={greeting} />
    </div>
  )
}

export default App
```

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

```jsx
import { useState } from "react"

const Banner = props => {
  const name = props.name
  return (
    <div>
      <p>
        {props.greeting} {name}
      </p>
      <button onClick={props.changeGreeting}>Change greeting</button>
    </div>
  )
}

function App() {
  const [greeting, setGreeting] = useState("Hello")

  const changeGreeting = () => {
    setGreeting("Howdy")
  }
  return (
    <div>
      <Banner
        name="Abhishek"
        greeting={greeting}
        changeGreeting={changeGreeting}
      />
    </div>
  )
}

export 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:

```jsx
const UserCard = props => {
  const name = props.user.name
  const role = props.user.role
  const age = props.user.age
  const profilePic = props.user.profilePic
  return (
    <div>
      <p>Name: {name}</p>
      <p>Role: {role}</p>
      <p>Age: {age}</p>
      <img src={profilePic} alt={name} />
    </div>
  )
}

function App() {
  const user = {
    name: "Abhishek",
    role: "Software Engineer",
    age: 27,
    profilePic: "image.jpg",
  }

  return (
    <div>
      <UserCard user={user} />
    </div>
  )
}

export 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:

```jsx
const UserCard = props => {
  const name = props.name
  const role = props.role
  const age = props.age
  const profilePic = props.profilePic
  return (
    <div>
      <p>Name: {name}</p>
      <p>Role: {role}</p>
      <p>Age: {age}</p>
      <img src={profilePic} alt={name} />
    </div>
  )
}

function App() {
  const user = {
    name: "Abhishek",
    role: "Software Engineer",
    age: 27,
    profilePic: "image.jpg",
  }

  return (
    <div>
      <UserCard
        name={user.name}
        role={user.role}
        age={user.age}
        profilePic={user.profilePic}
      />
    </div>
  )
}

export 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](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_syntax)

```jsx
const UserCard = props => {
  const name = props.name
  const role = props.role
  const age = props.age
  const profilePic = props.profilePic
  return (
    <div>
      <p>Name: {name}</p>
      <p>Role: {role}</p>
      <p>Age: {age}</p>
      <img src={profilePic} alt={name} />
    </div>
  )
}

function App() {
  const user = {
    name: "Abhishek",
    role: "Software Engineer",
    age: 27,
    profilePic: "image.jpg",
  }

  return (
    <div>
      <UserCard {...user} />
    </div>
  )
}

export 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.

```jsx
const UserCard = ({ name, role, age, profilePic }) => {
  return (
    <div>
      <p>Name: {name}</p>
      <p>Role: {role}</p>
      <p>Age: {age}</p>
      <img src={profilePic} alt={name} />
    </div>
  )
}

function App() {
  const user = {
    name: "Abhishek",
    role: "Software Engineer",
    age: 27,
    profilePic: "image.jpg",
  }

  return (
    <div>
      <UserCard {...user} />
    </div>
  )
}

export default App
```

As you may observe, we have used [JavaScript destructing](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment) 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](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Logical_OR#short-circuit_evaluation) to set a default name as shown below:

```jsx
const Banner = props => {
  const name = props.name || "user"
  return <div>Hello {name}</div>
}

function App() {
  return (
    <div>
      <Banner />
    </div>
  )
}

export default App
```

## Using default parameters

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

```jsx
const Banner = ({ name = "user" }) => {
  return <div>Hello {name}</div>
}

function App() {
  return (
    <div>
      <Banner />
    </div>
  )
}

export default App
```

## Using defaultProps

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

```jsx
const Banner = ({ name }) => {
  return <div>Hello {name}</div>
}

function App() {
  return (
    <div>
      <Banner />
    </div>
  )
}

Banner.defaultProps = {
  name: "user",
}

export default App
```

> Also, you can validate the type of the props using [prop-types](https://reactjs.org/docs/typechecking-with-proptypes.html)

# Renaming props

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

```jsx
const UserCard = ({ name, role: occupation }) => {
  return (
    <div>
      <p>Name: {name}</p>
      <p>Occupation: {occupation}</p>
    </div>
  )
}

function App() {
  return (
    <div>
      <UserCard name="Abhi" role="Software Engineer" />
    </div>
  )
}

export 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:

```jsx
const UserCard = ({ name, children }) => {
  return (
    <div>
      <p>Name: {name}</p>
      {children}
    </div>
  )
}

const UserIcon = ({ profilePic }) => {
  return <img src={profilePic} alt="profile" />
}

function App() {
  return (
    <div>
      <UserCard name="Abhi">
        <UserIcon profilePic="image.jpg" />
      </UserCard>
    </div>
  )
}

export 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:

```jsx
const UserCard = ({ name, icon }) => {
  return (
    <div>
      <p>Name: {name}</p>
      {icon}
    </div>
  )
}

const UserIcon = ({ profilePic }) => {
  return <img src={profilePic} alt="profile" />
}

function App() {
  return (
    <div>
      <UserCard
        name="Abhi"
        icon={<UserIcon profilePic="image.jpg" />}
      ></UserCard>
    </div>
  )
}

export 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.