Reputation: 4376
So I have a React.js component, and I want to loop through an object I import to add HTML options to it. Here is what I tried, which is both ugly and does not work:
import React from 'react';
import AccountTypes from '../data/AccountType';
const AccountTypeSelect = (props) => {
return (
<select id={props.id} className = {props.classString} style={props.styleObject}>
<option value="nothingSelected" defaultValue>--Select--</option>
{
$.each(AccountTypes, function(index) {
<option val={this.id}>this.name</option>
})
}
</select>
);
};
export default AccountTypeSelect;
I received this error in the console from the above code:
invariant.js?4599:38 - Uncaught Invariant Violation: Objects are not valid as a React child (found: object with keys {id, name, enabled, additionalInfo}). If you meant to render a collection of children, use an array instead or wrap the object using createFragment(object) from the React add-ons. Check the render method of AccountTypeSelect
.
Do I really need to convert each object into an array or wrap it with createFragment to use it? What is the best practice for this case?
Upvotes: 20
Views: 36186
Reputation: 2549
Points to note :
Your data is in an Object , not in an array : therefore to loop through it , you will have to use Object.keys(yourObject).map() instead of yourObject.map()
With this in mind ; here is the solution
var user = {
fname:'John',
lname : 'Doe',
email:'[email protected]'
}
class App extends Component {
render() {
return (
<p>
<ul>
{
Object.keys(user).map((oneKey,i)=>{
return (
<li key={i}>{user[oneKey]}</li>
)
})
}
</ul>
</p>
);
}
}
If you're using TypeScript:
(Object.keys(user) as (keyof typeof user)[]).map((oneKey,i)=>{
return (
<li key={i}>{user[oneKey]}</li>
)
})
Upvotes: 54
Reputation: 25269
Instead of $.each
use map
:
{AccountTypes.map(function(a) {
return (
<option key={a.id} val={a.id}>{a.name}</option>
);
})}
Upvotes: 10
Reputation: 3056
for rendering a list of children, you must add key
attribute for each child so React will render them properly.Try this:
With JQuery map ( good for functional programming)
{
$.map(AccountTypes, function(type,index) {
return <option key={type.id} val={type.id}>type.name</option>
})
}
With normal map :
{AccountTypes.map((type) => {
return <option key={type.id}
val={type.id}>
{type.name}
</option>
)}
Upvotes: 0
Reputation: 579
You should use map to loop:
{AccountTypes.map((accountType) =>
<option value={accountType.id}>{accountType.name}</option>)}
Upvotes: 0