## Props Handling
🔹 [[❞ React Fundamentals (R2R)|React Fundamentals]]
🔸 [[❜ Controlled components in React|Controlled components]], [[❞ Lifting State|Lifting State]], [[❞ React Side-Effects]]
Props are passed down the component tree from parent to child, and there are important tricks to doing this correctly.
### Object destructuring
You can use **object destructuring** to access props, since props is just an object for passing informaton from another object.
```js
const user = {
firstName: 'Mike',
lastName: 'Carlson',
};
// without object destructuring
const firstName = user.firstName;
const lastName = user.lastName;
// with object destructuring
const { firstName, lastName } = user;
```
Refactor the Search component's arrow function from concise body into block body to access the properties of props with the object destructuring in the component function's body.
Original
```js
const Search = (props) => (
<div>
<label htmlFor="search">Search: </label>
<input
id="search"
type="text"
value={props.search}
onChange={props.onSearch}
/>
</div>
```
Refactored
```js
const Search = (props) => {
const { search, onSearch } = props;
return (
<div> //...
}
```
Better - destructuring the props in the function signature of the compoenent
```js
const Search = ({ search, onSearch }) => (
<div>
<label htmlFor="search">Search: </label>
<input
id="search"
type="text"
value={search}
onChange={onSearch}
/>
</div>
);
```
### Nested Destructuring
Nested object can alsobe called in the function signature and then be immediately used in component elements.
```js
// Variation 1: Nested Destructuring
const Item = ({
item: {
title,
url,
author,
num_comments,
points,
},
}) => (
<li>
<span>
<a href={url}>{title}</a>
</span>
<span>{author}</span>
<span>{num_comments}</span>
<span>{points}</span>
</li>
);
```
This could also be broken apart into two components for Item and List, by first mapping the item into a List component and then creating an Item component that uses each of the properties.
```js
// Variation 2: Spread and Rest Operators
// 1. Step
const List = ({ list }) => (
<ul>
{list.map((item) => (
<Item
key={item.objectID}
title={item.title}
url={item.url}
author={item.author}
num_comments={item.num_comments}
points={item.points}
/>
))}
</ul>
);
const Item = ({ title, url, author, num_comments, points }) => (
<li>
<span>
<a href={url}>{title}</a>
</span>
<span>{author}</span>
<span>{num_comments}</span>
<span>{points}</span>
</li>
);
```
Two objects can be combined by using the spread operator.
```js
const profile = {
firstName: 'Robin',
lastName: 'Wieruch',
};
const address = {
country: 'Germany',
city: 'Berlin',
};
const user = {
...profile,
gender: 'male',
...address,
};
console.log(user);
// {
// firstName: "Robin",
// lastName: "Wieruch",
// gender: "male"
// country: "Germany,
// city: "Berlin",
// }
```
Using **spread** and **rest** operators, an object can have it's properties destructured and assigned to an List component by mapping the properties over and Item component.
```js
// Variation 2: Spread and Rest Operators
// Final Step
const List = ({ list }) => (
<ul>
{list.map(({ objectID, ...item }) => (
<Item key={objectID} {...item} />
))}
</ul>
);
```
Finally, the item is **spread** with its key/values pairs into the Item component. While this final variation is very concise, it also adds JavaScript features.
```js
const Item = ({ title, url, author, num_comments, points }) => (
<li>
<span>
<a href={url}>{title}</a>
</span>
<span>{author}</span>
<span>{num_comments}</span>
<span>{points}</span>
</li>
);
```
### References
1. Wieruch, Robin (2019). *Props Handling*. [Road to React](https://courses.robinwieruch.de/p/the-road-to-learn-react)