如何在反应循环一个对象?

新的反应和尝试循环对象属性,但反应抱怨对象不是有效的反应孩子,可以有人给我一些建议,如何解决这个问题?我已经添加了 createFragment,但是不完全确定需要把它放在哪里,或者应该采取什么方法?

JS

var tifs = {1: 'Joe', 2: 'Jane'};
var tifOptions = Object.keys(tifs).forEach(function(key) {
return <option value={key}>{tifs[key]}</option>
});

渲染功能

render() {
const model = this.props.model;


let tifOptions = {};


if(model.get('tifs')) {
tifOptions = Object.keys(this.props.model.get('tifs')).forEach(function(key) {
return <option value={key}>{this.props.model.get('tifs')[key]}</option>
});
}


return (
<div class={cellClasses}>


<div class="grid__col-5 text--center grid__col--bleed">
<h5 class="flush text--uppercase">TIF</h5>
<select id="tif" name="tif" onChange={this.handleChange}>
{tifOptions}
</select>
</div>


</div>
);
}

控制台错误

If you meant to render a collection of children, use an array instead or wrap the object using createFragment(object)
264609 次浏览

The problem is the way you're using forEach(), as it will always return undefined. You're probably looking for the map() method, which returns a new array:

var tifOptions = Object.keys(tifs).map(function(key) {
return <option value={key}>{tifs[key]}</option>
});

If you still want to use forEach(), you'd have to do something like this:

var tifOptions = [];


Object.keys(tifs).forEach(function(key) {
tifOptions.push(<option value={key}>{tifs[key]}</option>);
});

Update:

If you're writing ES6, you can accomplish the same thing a bit neater using an arrow function:

const tifOptions = Object.keys(tifs).map(key =>
<option value={key}>{tifs[key]}</option>
)

Here's a fiddle showing all options mentioned above: https://jsfiddle.net/fs7sagep/

I highly suggest you to use an array instead of an object if you're doing react itteration, this is a syntax I use it ofen.

const rooms = this.state.array.map((e, i) =>(<div key={i}>{e}</div>))

To use the element, just place {rooms} in your jsx.

Where e=elements of the arrays and i=index of the element. Read more here. If your looking for itteration, this is the way to do it.

You can use it in a more compact way as:

const tifs = {1: 'Joe', 2: 'Jane'};
...


return (
<select id="tif" name="tif" onChange={this.handleChange}>
{ Object.entries(tifs).map((t,k) => <option key={k} value={t[0]}>{t[1]}</option>) }
</select>
)

And another slightly different flavour:

 Object.entries(tifs).map(([key,value],i) => <option key={i} value={key}>{value}</option>)

you could also just have a return div like the one below and use the built in template literals of Javascript :

const tifs = {1: 'Joe', 2: 'Jane'};


return(


<div>
{Object.keys(tifOptions).map((key)=>(
<p>{paragraphs[`${key}`]}</p>
))}
</div>
)
const tifOptions = [];


for (const [key, value] of Object.entries(tifs)) {
tifOptions.push(<option value={key} key={key}>{value}</option>);
}


return (
<select id="tif" name="tif" onChange={this.handleChange}>
{ tifOptions }
</select>
)

You can use map function

{Object.keys(tifs).map(key => (
<option value={key}>{tifs[key]}</option>
))}

When I use Object.entries with map, I use Array Destructuring like the following and just call them directly.

Object.entries(tifs).map(([key, value]) => (
<div key={key}>{value}</div>
));
{
Object.entries(tifOptions).map(([key, value], index) =>
console.log("Key" + Key + "::>" + "Value" + value);
)}