NyaSol
NyaSol

Reputation: 567

Understand the usage of rest and spread parameters with the map function

I want to understand how to properly use the ... operator in js, especially with the js map function.

Say we have the following data:

const SHOP_DATA = [
    {
      id: 1,
      title: 'Hats',
      routeName: 'hats',
      items: [
        {
          id: 1,
          name: 'Brown Brim',
          imageUrl: 'https://i.ibb.co/ZYW3VTp/brown-brim.png',
          price: 25
        }]
    }
]

Now I want to send values as props to another component:

SHOP_DATA.map(({ id, ...otherProps }) => (
          <CollectionPreview key={id} {...otherProps} />

If I understood correctly the first ... is a rest operator, which means we are pooling the values to a new array. and the second ... is a spread operator which means we are spreading those values from the array

And then we need to use the ... operator one more time inside the ColectionPreview to spread them out.

const CollectionPreview = ({ id, ...otherProps }) => {

I don't understand the data flow, why what we just did is equivalent to do :

SHOP_DATA.map(({ id, title , items }) => (
          <CollectionPreview key={id} title = {title} items = {items} />

Upvotes: 2

Views: 521

Answers (2)

Dyo
Dyo

Reputation: 4464

SHOP_DATA.map(({ id, ...otherProps })

Here you're destructuring each SHOP_DATA's objects attributes, and using the object's rest operator which inits an object called otherProps with all of the object attributes minus the ones specified before ("id" in this case) :

otherProps = {
    title: 'Hats',
    routeName: 'hats',
    items: [
        {
            id: 1,
            name: 'Brown Brim',
            imageUrl: 'https://i.ibb.co/ZYW3VTp/brown-brim.png',
            price: 25,
        },
    ],
};

<CollectionPreview key={id} {...otherProps} />

Here you are using the JSX spread operator, this is a bit different than the object spread operator, it spreads all attributes of an object to the component props naming them by the attributes names, result :

<CollectionPreview key={id} title="Hats" routeName="hats" items={[{ id: 1, name: "Brown Brim", etc.. }]} />

const CollectionPreview = ({ id, ...otherProps }) => {

In the component declaration you're not forced to use the object rest operator, if you know your props names you can use them individually like this :

const CollectionPreview = ({ id, title, routeName, items }) => {

Upvotes: 3

Praneeth Paruchuri
Praneeth Paruchuri

Reputation: 1032

For this you also need to be familiar with destructuring.

If you have an object:

const human = { name: 'John', age: 20, sex: 'Male'}

You can take out the props of the object out like:

const {name, age, sex} = human

Now, name -> 'John, age -> 20, sex -> 'Male'

But if you do

const {name, ...rest} = human
name -> 'John'
rest -> { age: 20, sex: 'Male'}

Now let's go to your code:

SHOP_DATA.map(({ id, ...otherProps })

Here you are mapping through the array and destructuring the object on the fly.

id -> id 
otherProps -> { 
              title: 'Hats',
              routeName: 'hats',
              items: [
                      {
                        id: 1,
                        name: 'Brown Brim',
                        imageUrl: 'https://i.ibb.co/ZYW3VTp/brown-brim.png',
                        price: 25
                     }]
              }

And hence

 <CollectionPreview key={id} {...otherProps} />

will turn into

 <CollectionPreview key={id} title={title} routerName={routeName} items={items} />

Hope this was helpful.

Upvotes: 2

Related Questions