Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Most efficient way of rendering JSX elements when iterating on array of data in React

I have an array which contains objects. I am creating a map of this array to renders the names with a span component.

let data = [{"id": "01", "name": "Hi"}, {"id": "02", "name": "Hello"}];

I have been using the below two different functionalities to iterate on that array of objects, and using map to render JSX elements.

Functionality1:

import React, { Component } from 'react';
class App extends Component {

  render() {
    let data = [{"id": "01", "name": "Hi"}, {"id": "02", "name": "Hello"}];
    const items = data.map((key, i) => {
      return <span key={key.id}>{key.name}</span>;
    });
    return (
      <div>
        {items}
      </div>
    );
  }
}

export default App;

Functionality2:

import React, { Component } from 'react';
class App extends Component {

  render() {
    let data = [{"id": "01", "name": "Hi"}, {"id": "02", "name": "Hello"}];
    let rows = [];
    data.map((key, i) => {
      rows.push(<span key={key.id}>{key.name}</span>);
    });
    return (
      <div>
        {rows}
      </div>
    );
  }
}


export default App;

I known to the above two different ways of using map and rendering JSX elements. Is there any other ways of doing the same, apart from these two? If so, which is recommended?

like image 809
Hemadri Dasari Avatar asked Sep 05 '18 03:09

Hemadri Dasari


People also ask

How do I render an array of elements in JSX?

To render an array of components in React you simply need to pass the array into JSX by wrapping it in curly braces, just be sure that your components each have a unique key prop because React will use this when rendering it to avoid bugs.

How do you iterate through an array in Reactjs?

To loop through an array of objects in React:Use the map() method to iterate over the array. The function you pass to map() gets called for each element in the array. The method returns a new array with the results of the passed in function.

Which method will you use in React to display components for each object in an array?

Rendering Multiple Elements To render multiple JSX elements in React, you can loop through an array with the . map() method and return a single element.

How do I render JSX elements in react?

The key prop helps React keep track of JSX elements and identify any changes in the array. Alternatively, you can also use regular loops like the for loop to render JSX elements. Create a separate function called renderUsers () in the component.

How do you iterate through an array in JSX?

Using the map () Method The map () method is the most commonly used function to iterate over an array of data in JSX. You can attach the map () method to the array and pass a callback function that gets called for each iteration. When rendering the User component, pass a unique value to the key prop.

How to iterate list of objects in react render?

It uses es6 arrow function for an call-back for-of loop is new way to iterate objects. As react render returns one element, before returning list, construct list using different approaches mentioned above and return a final array.

How to render more than one element in a JSX component?

In JSX, to render more than one element in a component you must add a wrapper around them. In this example, you will first return a list of items without looping through an array: To fix this error you need to wrap the block of li elements in a wrapper. For a list you can wrap them in an ol or ul element:


Video Answer


3 Answers

Mostly, I follow this rule:

Create a component which renders the items

// in some file
export const RenderItems = ({data}) => {
  return data && data.map((d, i) => <span key={d.id}>{d.name}</span>) || null
}

Hook the RenderItems

import { RenderItems } from 'some-file'

class App extends Component {
  render() {
    // you may also define data here instead of getting data from props
    const { data } = this.props
    return (
      <div>
        <RenderItems data={data} />
      </div>
    )
  }
}

Attach the data in the component

const data = [{"id": "01", "name": "Hi"}, {"id": "02", "name": "Hello"}]
<App data={data} />

Following this rule will not impact on performance even with your second example of code ie. pushing items in an array and rendering the items. Because, you're not directly working inside the render hook. Always take care that render hook wouldn't implement any logic inside it directly.


Further, I wouldn't create id just for using key:

const data = [{"name": "Hi"}, {"name": "Hello"}]
//... and when using index as key
.map((d, i) => <span key={'item-'+i}>
// or,
.map((d, i) => <span key={'item-'+i+'-'+d.name}>

See this post why I follow this syntax while using index as key.


Update:

If you want to avoid unnecessary html tags being used, you can use React.Fragment

export const RenderItems = ({data}) => {
  return data && 
    data.map(
      (d, i) => <React.Fragment key={d.id}>{d.name}</React.Fragment>
    ) || null
}
// and when rendering, you just return the component
return <RenderItems data={data} />

Note:

  1. You can use <></> as an alias for <React.Fragment></React.Fragment> only if you don't have any additional property. Since we're using key property on it, not using it.
  2. Take a look at this to make support for short notation of React.Fragment.

Example using <></>:

<>{d.name}</>

This will be rendered d.name's value in html without any tag. This is considered best when we specifically transform our existing design to react application. Or, there might be other cases. Like, we are going to display a definition list:

<dl>
  <dt></dt>
  <dd></dd>
  <dt></dt>
  <dd></dd>
  <dt></dd>
</dl>

And we don't want to attach unnecessary html tag, then using Fragment will make our life easier:

Example:

<>
  <dt>{d.term}</dt>
  <dd>{d.definition}</dd>
</>

The most important case will be for rendering td element in tr (a TR component). If we don't, then we're breaking the rule of HTML. The component will not be rendered properly. In react, it will throw you an error.

Update2:

Also, if you have long list of props like below:

const {
  items,
  id,
  imdbID,
  title,
  poster,
  getMovieInfo,
  addToFavorites,
  isOpen,
  toggleModal,
  closeModal,
  modalData,
} = props

You may consider destructuring like:

const { items, ...other } = props
// and in your component you can use like:
<div modalData={other.modalData}>

But, personally I prefer using first example code. It's because while developing I won't need to look back to other component or look for the console each and every time. In the given example there's key like modalData={} so we easily maintain modalData={other.modalData}. But what if it is needed to code like <div>{modalData}</div>? Then, you may also agree with my preference.

like image 86
Bhojendra Rauniyar Avatar answered Oct 23 '22 23:10

Bhojendra Rauniyar


I would do this

const data = [{id: 1, name: 'a'}, {id: 2, name: 'b'}];

export default class App extends PureComponent {
  render() {
    return (
      <div>
        {data.map(({ id, name }) => <span key={id}>{name}</span>)}
      </div>
    );
  }
}

Now, your data is not reinstantiated on every render, and you don't have to garbage collect any unnecessary variable declarations.

like image 12
Daniel Lizik Avatar answered Oct 23 '22 23:10

Daniel Lizik


The first way is better.

  1. Array.prototype.map creates an array behind the scenes and returns it after applying the modification on each element. Functionality-1 creates two arrays, while Functionality-2 creates three.

  2. Functionality-1 reads better. It's how React code usually being written. For a simple element like this, I'd save the const definition for items and put the map statement in the JSX to be returned directly.

like image 8
Ying Zuo Avatar answered Oct 23 '22 22:10

Ying Zuo