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\
The function toSpan
can be reused.
class App extends React.Component {
render() {
const data = [{id: `01`, name: `Hi`}, {id: `02`, name: `Hello`}]
const toSpan = ({id, name}) => <span key={id}>{name}</span>
return (
<div>{data.map(toSpan)}</div>
)
}
}
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.
the first method is correct. use the map function to iterate through the array.
export default class App extends React.Component{
constructor(props){
super(props);
this.state = {
data: [{"id": "01", "name": "Hi"}, {"id": "02", "name": "Hello"}];
};
}
render(){
return(
<div>
{this.state.data.map((data,index)=>
<span key={data.id}>{data.name}</span>
)}
);
}
}
Generally, for
or while
statement is the most efficient way to iterate an array. The way a small array is processed in non-critical place can be considered microoptimisation.
The use of map
is idiomatic in React components because it's fast enough and can return a value as a part of an expression.
While this is an antipattern:
let rows = [];
data.map((key, i) => {
rows.push(<span key={key.id}>{key.name}</span>);
});
map
is supposed to map array elements to other values (hence the name), not to iterate an array instead of forEach
or other loop. This problem can be tracked with ESLint array-callback-return rule.
The component is stateless and doesn't need to be Component
class. It can be functional component or PureComponent
class. Since data
is constant, it doesn't need to be assigned on each render:
const data = [{"id": "01", "name": "Hi"}, {"id": "02", "name": "Hello"}];
const App = props => <div>
{data.map(({ id, name }) => <span key={id}>{name}</span>)}
</div>;
The first way is better.
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.
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.
I'd go with the map
inside the return(...)
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:
const Spanner = props => { return <span key={ props.data.id }>{ props.data.name }</span> };
class App extends Component {
render() {
let data = [{"id": "01", "name": "Hi"}, {"id": "02", "name": "Hello"}];
return (
<div>
{
data.map( (item, ind) => {
return (<Spanner key={item.id} data={item.name} />);
})
}
</div>
);
}
}
}
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"}];
const UserWidget = (props) => {
return (
<div>
<h4>{ props.type }</h4>
<Spanner key={ props.key } data={ props.name }/>
</div>
);
}
// now both the UserWidget and the Spanner Components can be used wherever required
// say a dashboard Component wants to use the UserWidget
class Dashboard extends Component {
render() {
let data = [{"id": "01", "name": "Hi", "userType": "Admin"}, {"id": "02", "name": "Hello", "userType": "Client"}];
return (
<div>
{
data.map( (item, ind) => {
return (<UserWidget type={ item.userType } key={item.id} data={item.name} />);
})
}
</div>
);
}
}
}
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 key userType
.
Again this is how I'd do it.