在React中渲染array.map()

时间:2016-07-09 14:46:58

标签: javascript reactjs

我遇到的问题是我尝试使用数据数组来呈现<ul>元素。在下面的代码中,console.log工作正常,但列表项目没有出现。

var Main = React.createClass({
  getInitialState: function(){
    return {
      data: dataRecent
    }
  },

  render: function(){
    return (
      <div>
        <ul>
          {
           this.state.data.map(function(item, i){
             console.log('test');
             <li>Test</li>
           })
         }
        </ul>
      </div>
    )
  }
});

ReactDOM.render(<Main />, document.getElementById('app')); 

我做错了什么?请随意指出任何不是最佳做法。感谢。

9 个答案:

答案 0 :(得分:44)

Gosha Arinich是对的,您应该返回<li>元素。 但是,在这种情况下,你应该在浏览器控制台中得到令人讨厌的红色警告

  

数组或迭代器中的每个子节点都应该有一个唯一的“键”支柱。

所以,您需要在列表中添加“key”:

this.state.data.map(function(item, i){
  console.log('test');
  return <li key={i}>Test</li>
})

或删除console.log()并使用es6 arrow functions做一个漂亮的oneliner:

this.state.data.map((item,i) => <li key={i}>Test</li>)

重要更新

上面的答案是解决当前问题,但是在评论中提到Sergey:如果要进行一些过滤和排序,则使用取决于地图索引的键是BAD。在这种情况下,如果item.id已经存在,请使用id,或者只为其生成唯一ID。

答案 1 :(得分:5)

你没有回来。改为

this.state.data.map(function(item, i){
  console.log('test');
  return <li>Test</li>;
})

答案 2 :(得分:3)

您隐式返回undefined。你需要返回元素。

this.state.data.map(function(item, i){
  console.log('test');
  return <li>Test</li>
})

答案 3 :(得分:3)

let durationBody = duration.map((item, i) => {
      return (
        <option key={i} value={item}>
          {item}
        </option>
      );
    });

答案 4 :(得分:0)

此解决方案的实现遇到了问题。

如果您要遍历自定义组件,并且希望共享状态,则该组件将不可用,因为.map()范围无法识别一般的state()范围。 我来到了这个解决方案:

`

class RootComponent extends Component() {
    constructor(props) {
        ....
        this.customFunction.bind(this);
        this.state = {thisWorks: false}
        this.that = this;
    }
    componentDidMount() {
        ....
    }
    render() {
       let array = this.thatstate.map(() => { 
           <CustomComponent that={this.that} customFunction={this.customFunction}/>
       });

    }
    customFunction() {
        this.that.setState({thisWorks: true})
    }
}



class CustomComponent extend Component {

    render() {
        return <Button onClick={() => {this.props.customFunction()}}
    }
}

在没有这个的构造函数绑定中。 根组件内部对函数/方法的每次使用都应与this.that

一起使用

答案 5 :(得分:0)

加上Dmitry的答案,如果您不想手动处理唯一的密钥ID,可以按照React documentation的建议使用React.Children.toArray

React.Children.toArray

将子级不透明数据结构返回为平面数组,并为每个子级分配了键。如果要在渲染方法中操纵子级的集合,特别是如果要在传递它之前重新排序或切片this.props.children,则很有用。

  

注意:

     

React.Children.toArray()会在平整子级列表时更改键以保留嵌套数组的语义。也就是说,toArray在返回的数组中的每个键之前添加前缀,以便每个元素的键的作用域都限于包含它的输入数组。

 <div>
    <ul>
      {
        React.Children.toArray(
          this.state.data.map((item, i) => <li>Test</li>)
        )
      }
    </ul>
  </div>

答案 6 :(得分:0)

德米特里·布林(Dmitry Brin)的回答对我有用,但有一个警告。就我而言,我需要在列表标记之间运行一个函数,该函数需要嵌套的JSX大括号。下面的示例JSX对我有用:

{this.props.data().map(function (object, i) { return <li>{JSON.stringify(object)}</li> })}

如果您不使用嵌套的JSX大括号,例如:

{this.props.data().map(function (object, i) { return <li>JSON.stringify(object)</li>})}

然后在HTML输出中获得“ JSON.stringify(object)”列表,这可能不是您想要的。

答案 7 :(得分:0)

使用无状态功能组件我们将不会使用this.state。像这样

 {data1.map((item,key)=>
               { return
                <tr key={key}>
                <td>{item.heading}</td>
                <td>{item.date}</td>
                <td>{item.status}</td>
              </tr>
                
                })}

答案 8 :(得分:-2)

import React, { Component } from 'react';

class Result extends Component {


    render() {

           if(this.props.resultsfood.status=='found'){

            var foodlist = this.props.resultsfood.items.map(name=>{

                   return (


                   <div className="row" key={name.id} >

                  <div className="list-group">   

                  <a href="#" className="list-group-item list-group-item-action disabled">

                  <span className="badge badge-info"><h6> {name.item}</h6></span>
                  <span className="badge badge-danger"><h6> Rs.{name.price}/=</h6></span>

                  </a>
                  <a href="#" className="list-group-item list-group-item-action disabled">
                  <div className="alert alert-dismissible alert-secondary">

                    <strong>{name.description}</strong>  
                    </div>
                  </a>
                <div className="form-group">

                    <label className="col-form-label col-form-label-sm" htmlFor="inputSmall">Quantitiy</label>
                    <input className="form-control form-control-sm" placeholder="unit/kg"  type="text" ref="qty"/>
                    <div> <button type="button" className="btn btn-success"  
                    onClick={()=>{this.props.savelist(name.item,name.price);
                    this.props.pricelist(name.price);
                    this.props.quntylist(this.refs.qty.value);
                    }
                    }>ADD Cart</button>
                        </div>



                  <br/>

                      </div>

                </div>

                </div>

                   )
            })



           }



        return (
<ul>
   {foodlist}
</ul>
        )
    }
}

export default Result;