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?
I'd go with the
map
inside thereturn(...)
as map returns an array. It's cleaner and readable, something I personally strive for.To add on to the answer, if the array
data
might change down the lane I'd go with creating a new stateless dump component:This way we can use this Spanner Component as a common component shared among different component. And in case the
data
changes over time ( which most of the time, does) you can write a wrapper function to the Spanner component and call the new function wherever required.data=[{"id": "01", "name": "Hi", "userType": "Admin"}, {"id": "02", "name": "Hello", "userType": "Client"}];
This way you're not repeating yourself, and your App Component still has the expected behavior even if now the new
data
array has the new keyuserType
. Again this is how I'd do it.You may use this for best understanding
Here you can understand that the name belongs to with attribute.
I would do this
Now, your
data
is not reinstantiated on every render, and you don't have to garbage collect any unnecessary variable declarations.Mostly, I follow this rule:
Create a component which renders the items
Hook the RenderItems
Attach the data in the component
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: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
Note:
<></>
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.React.Fragment
.Example using
<></>
: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:And we don't want to attach unnecessary html tag, then using Fragment will make our life easier:
Example:
The most important case will be for rendering
td
element intr
(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:
You may consider destructuring like:
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 maintainmodalData={other.modalData}
. But what if it is needed to code like<div>{modalData}</div>
? Then, you may also agree with my preference.the first method is correct. use the map function to iterate through the array.
The function
toSpan
can be reused.