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