如何在React中循环对象?


75

刚接触React并尝试循环对象属性,但是React抱怨对象不是有效的React子代,有人可以给我一些如何解决此问题的建议吗?我添加了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)

我之前也遇到过类似的错误。.map()足够奇怪的使用对我来说是解决方法。这也很有趣:stackoverflow.com/questions/37997893/…–
justDan

Answers:


168

问题在于您的使用方式forEach(),因为它总是会返回undefined。您可能正在寻找map()返回新数组的方法:

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

如果仍然要使用forEach(),则必须执行以下操作:

var tifOptions = [];

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

更新:

如果您正在编写ES6,则可以使用箭头功能来完成相同的任务:

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

这是显示上面提到的所有选项的小提琴:https : //jsfiddle.net/fs7sagep/


13

您可以将其以更紧凑的方式使用:

var 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>
)

还有另一种略有不同的味道:

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

3

您也可以像下面这样一个返回div,并使用Javascript的内置模板文字:

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

return(

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

0
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>
)

-7

我强烈建议您在执行反应时使用数组而不是对象,这是我经常使用的语法。

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

要使用元素,只需放置 {rooms}在您的jsx中。

其中e =数组元素,i =元素索引。在这里阅读更多。如果您正在寻找发信号,这就是这样做的方法。


1
使用对象时,键通常是ID,而不是索引。但是,如果键是所有索引,则我同意。
tobiasandersen '16

感谢您的评论,但我不是在谈论对象。对我来说,使用数组似乎是最好的,并且文档提供的效果也不错。键根本不是必需的,它们是用来保持元素顺序的。我没有发明密钥的索引方法,这是写在docs中的:P
alex1997'Oct11''16

1
数组并非总是最佳选择,即使经常如此。例如,在缓存内容时,我通常转向Map:s或对象。尽管React会根据索引添加键,但是当您没有明确提供键时,肯定会有用例。
tobiasandersen '16

这根本没有回答问题
reggaeguitar
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.