简体   繁体   English

在 React 中渲染 array.map()

[英]Rendering an array.map() in React

I am having a problem where I am trying to use array of data to render a <ul> element.我在尝试使用数据数组呈现<ul>元素时遇到问题。 In the code below the console.log 's are working fine, but the list items aren't appearing.在下面的代码中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')); 

What am I doing wrong?我究竟做错了什么? Please feel free to point out anything that isn't best practice.请随时指出任何不是最佳实践的地方。

Gosha Arinich is right, you should return your <li> element. Gosha Arinich是对的,你应该返回你的<li>元素。 But, nevertheless, you should get nasty red warning in the browser console in this case但是,在这种情况下,您应该在浏览器控制台中收到讨厌的红色警告

Each child in an array or iterator should have a unique "key" prop.数组或迭代器中的每个孩子都应该有一个唯一的“key”道具。

so, you need to add "key" to your list:因此,您需要将“密钥”添加到您的列表中:

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

or drop the console.log() and do a beautiful oneliner, using es6 arrow functions :或删除console.log()并使用 es6 箭头函数做一个漂亮的 oneliner:

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

IMPORTANT UPDATE :重要更新

The answer above is solving the current problem, but as Sergey mentioned in the comments: using the key depending on the map index is BAD if you want to do some filtering and sorting.上面的答案是解决当前的问题,但正如Sergey在评论中提到的那样:如果你想做一些过滤和排序,使用取决于地图索引的键是不好的。 In that case use the item.id if id already there, or just generate unique ids for it.在这种情况下,如果id已经存在,请使用item.id ,或者只为其生成唯一的 id。

You are not returning.你不回来了。 Change to改成

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

Using Stateless Functional Component We will not be using this.state.使用无状态功能组件我们不会使用 this.state。 Like this像这样

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

You are implicitly returning undefined .您正在隐式返回undefined You need to return the element.您需要返回元素。

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

Add up to Dmitry's answer, if you don't want to handle unique key IDs manually, you can use React.Children.toArray as proposed in the React documentation加起来 Dmitry 的回答,如果您不想手动处理唯一键 ID,您可以按照React 文档中的建议使用React.Children.toArray

React.Children.toArray React.Children.toArray

Returns the children opaque data structure as a flat array with keys assigned to each child.以平面数组的形式返回子级不透明数据结构,并为每个子级分配键。 Useful if you want to manipulate collections of children in your render methods, especially if you want to reorder or slice this.props.children before passing it down.如果你想在你的渲染方法中操作孩子的集合,特别是如果你想在传递它之前重新排序或切片 this.props.children 时很有用。

Note:笔记:

React.Children.toArray() changes keys to preserve the semantics of nested arrays when flattening lists of children. React.Children.toArray()在展平子列表时更改键以保留嵌套数组的语义。 That is, toArray prefixes each key in the returned array so that each element's key is scoped to the input array containing it.也就是说, toArray 为返回数组中的每个键添加前缀,以便每个元素的键的范围都限定为包含它的输入数组。

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

Best Answer:最佳答案:

import React, { useState } from 'react';
import './App.css';

function App() {
  // Array of objects containing our fruit data
  let fruits = [
    { label: "Apple", value: "🍎" },
    { label: "Banana", value: "🍌" },
    { label: "Orange", value: "🍊" }
  ]

  // Using state to keep track of what the selected fruit is
  let [fruit, setFruit] = useState("⬇️ Select a fruit ⬇️")

  // Using this function to update the state of fruit
  // whenever a new option is selected from the dropdown
  let handleFruitChange = (e) => {
    setFruit(e.target.value)
  }

  return (
    <div className="App">
      {/* Displaying the value of fruit */}
      {fruit}
      <br />

      <select onChange={handleFruitChange}>
        {
        fruits.map((fruit) => <option value={fruit.value}>{fruit.label}</option>)
        }
      </select>
    </div>
  );
}

export default App;

I've come cross an issue with the implementation of this solution.我遇到了实施此解决方案的问题。

If you have a custom component you want to iterate through and you want to share the state it will not be available as the .map() scope does not recognize the general state() scope.如果您有一个想要迭代的自定义组件并且想要共享状态,它将不可用,因为 .map() 范围无法识别一般 state() 范围。 I've come to this solution:我来到了这个解决方案:

` `

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()}}
    }
}

In constructor bind without this.that Every use of any function/method inside the root component should be used with this.that在没有 this.that 的构造函数中绑定根组件内的任何函数/方法的每次使用都应该与this.that一起使用

Dmitry Brin's answer worked for me, with one caveat.德米特里布林的回答对我有用,但有一个警告。 In my case, I needed to run a function between the list tags, which requires nested JSX braces.就我而言,我需要在列表标签​​之间运行一个函数,这需要嵌套的 JSX 大括号。 Example JSX below, which worked for me:下面的示例 JSX,对我有用:

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

If you don't use nested JSX braces, for example:如果你不使用嵌套的 JSX 大括号,例如:

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

then you get a list of "JSON.stringify(object)" in your HTML output, which probably isn't what you want.然后你会在你的 HTML 输出中得到一个“JSON.stringify(object)”列表,这可能不是你想要的。

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;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM