Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

React Array converted to object when passed as a prop to SFC

Tags:

reactjs

I have a react function and I am passing an array of objects as a prop. When the component renders, the array is nested into an object of the same name.

Why is it being nested? And can I do something to coerce it back to an array?

Here is the code (and a link to a pen (https://codepen.io/bluesixty/pen/PJQKVq?editors=0010):

const tags = [
      {
        name: 'ios',
        link: '',
      },
      {
        name: 'ANDROID',
        link: '',
      },
      {
        name: 'REACT',
        link: '',
      },
      {
        name: 'javascript',
        link: '',
      },
    ]


const App = tagList => {

    return (
      <div>
        This is a React component!
        <ul>
          {tagList.tagList.map((tag, i) => (
            <li>
              {tag.name}
            </li>
        ))}
        </ul>
      </div>
    );
  }


ReactDOM.render(
    <App tagList={tags}/>,
  document.getElementById('root')
);

Removing the second tagList in the .map fails with 'tagList.map is not a function'. Which is true, it is an object now????

{tagList.map((tag, i) => (
like image 578
bluesixty Avatar asked Oct 06 '17 19:10

bluesixty


People also ask

Can you pass an array as a prop in React?

To pass an array as a prop to a component in React, wrap the array in curly braces, e.g. <Books arr={['A', 'B', 'C']} /> . The child component can perform custom logic on the array or use the map() method to render the array's elements.

Can you pass an object as a prop in React?

Use the spread syntax (...) to pass an object as props to a React component, e.g. <Person {... obj} /> . The spread syntax will unpack all of the properties of the object and pass them as props to the specified component.

Can we pass Javascript object and array as props in React?

As you all know, properties which are shortly called as props is one of fundamental blocks of React. Props will allow you to pass the parameters between the components, they could be strings, numbers, object or arrays.


2 Answers

A functional component receives props as the first argument, so the correct code is:

const App = props => {

    return (
      <div>
        This is a React component!
        <ul>
          {props.tagList.map((tag, i) => (
            <li>
              {tag.name}
            </li>
        ))}
        </ul>
      </div>
    );
  }

It can also be written like this:

const App = ({ tagList }) => (
  <div>
    This is a React component!
    <ul>
      {tagList.map(({ name }, i) => (
        <li>
          {name}
        </li>
      ))}
    </ul>
  </div>
);
like image 99
Kirill Bulygin Avatar answered Sep 22 '22 16:09

Kirill Bulygin


Your 1st question:

Why is it being nested?

When you pass data to any React component, you pass it as 'props'. In your case, the data you want to pass is your tags array populated with objects.

The function defining the App component has props as its parameter. When you pass your argument to it, you pass it as an object argument, i.e. props is an object containing the props you pass to a component.

That's why if you had a plain variable:

let greeting = 'Hello World'

And passed it as props:

<App content={greeting}/>

The props object would look like this:

props = {
   greeting: 'Hello World'
}

and you'd access it in the App component function as such:

{props.content}

The variable passed as an argument is an object parameter for the function.

Your 2nd question:

And can I do something to coerce it back to an array?

Yes, you can. Within the App component:

 const tags = [];
  Object.keys(props).forEach(function(prop) {
    tags.push(...props[prop]);
  });

  console.log(tags); // now an array with your tags

However, you don't need to. You can use props.tagList as mentioned in the answer above.

Hope that clears it up for others.

like image 42
Joel H Avatar answered Sep 20 '22 16:09

Joel H