props.items.map不是使用React

时间:2017-09-27 21:29:26

标签: javascript reactjs

我正在使用React作为初学者,我查找了我得到的错误,大多数人说你不能使用map对象,它必须是一个数组。但是当我把它放在console.log中时,我会收到以下关于props.items的数据:

[{
  ItemKey: 82521,
  ISBN: "158344422X",
  Title: "Butterflies And Moths",
  Publisher: "Benchmark Education",
  Illustrator: " "
}, {
  ItemKey: 85938,
  ISBN: "9780452274426",
  Title: "In the Time of the Butterflies",
  Publisher: "Penguin Plume",
  Illustrator: " "
}]

所以它返回一个数组。但我仍然得到地图不是函数错误。这是我的代码:

function ItemGrid (props){
    return (
        <ul className='items-list'>
            {props.items.map(function(item, index){
                <li key={item.Title} className="items-list-item">
                </li>
            })}
        </ul>
    )
}

有没有人看到我写的代码或返回的对象有什么异常?

编辑:以下是我获取数据的方式:

module.exports = {
    fetchItems: function(){
        var encodedURI = window.encodeURI('http://localhost:8081/items?Title=butterflies', { crossdomain: true });
        return axios.get(encodedURI).then(function(response){
            return response.data;
        });
    }
}

我通过以下方式将数据传递给ItemGrid:

componentDidMount(){
    api.fetchItems().then(function(items){
        this.setState(function(){
            return {
                items: items
            }
        })
    }.bind(this));
}

render() {
    return (<div>
        <ItemGrid items={this.state.items} />
    </div>);
}

一旦数据存在,我也无法显示li项目:

<ul className='items-list'>

            {items && items.map(function (item, index) {
                console.log(item);
                <li key={index} className='items-list-item'>
                    item.Title
                </li>
            })}
        </ul>

3 个答案:

答案 0 :(得分:1)

渲染函数可以并且将被调用多次,第一次通常没有任何数据。

因此,在尝试使用map()函数迭代数据之前,需要检查数据是否存在。

如果props.items不存在,您可以返回一些简单的内容,如null或甚至“正在加载”,下次(当数据存在时)它将按预期工作。

所以你的新代码可能就是这样(只有在定义props.items时才会呈现):

function ItemGrid (props){
    return (
        <ul className='items-list'>
            {props.items && props.items.map(function(item, index){
                <li key={item.Title} className="items-list-item">
                </li>
            })}
        </ul>
    )
}

答案 1 :(得分:1)

正确的解决方案取决于如何检索数据。如果它是脚本中的一个简单JS数组,那么在安装组件时数据应该可用。

&#13;
&#13;
var data = [{
    ItemKey: 82521,
    ISBN: "158344422X",
    Title: "Butterflies And Moths",
    Publisher: "Benchmark Education",
    Illustrator: " "
  }, {
    ItemKey: 85938,
    ISBN: "9780452274426",
    Title: "In the Time of the Butterflies",
    Publisher: "Penguin Plume",
    Illustrator: " "
  }];

function ItemGrid(props) {
  var items = props.items;

  return ( 
    <ul className='items-list'> {
      items.map(function(item, index) { 
        return (<li key={item.ItemKey} className="items-list-item">{item.Title}</li>)
      })
    } </ul>
  )
}

ReactDOM.render(<ItemGrid items={data} />, document.getElementById("app"));
&#13;
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>

<div id="app"></div>
&#13;
&#13;
&#13;

另一方面,如果您从异步请求中检索数据,则在安装组件时可能无法使用该数据,并且在props.items未定义时您需要处理该情况/空/空。在下面的示例中,我们将<ItemsGrid/>组件包装在<Parent/>组件中,该组件将items作为道具传递给<ItemsGrid/>。最初itemsnull,3秒后更改为数组。这模拟了异步数据源。

itemsnull时,我们会返回显示Loading...的列表,当items更改为有效值时,我们会显示这些项目。

&#13;
&#13;
class Parent extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      data: null
    };
    
    window.setTimeout(function(){
      this.setState({
        data: [{
          ItemKey: 82521,
          ISBN: "158344422X",
          Title: "Butterflies And Moths",
          Publisher: "Benchmark Education",
          Illustrator: " "
        }, {
          ItemKey: 85938,
          ISBN: "9780452274426",
          Title: "In the Time of the Butterflies",
          Publisher: "Penguin Plume",
          Illustrator: " "
        }]
      })
    }.bind(this), 3000);
  }

  render() {
    return ( 
      <ItemGrid items={this.state.data} />
    )
  }
}

function ItemGrid(props) {
  var items = props.items;
  
  if (!items) {
    return (
      <ul>
        <li>Loading...</li>
      </ul>
    );
  }

  return ( 
    <ul className='items-list'> {
      items && items.map(function(item, index) { 
        return (<li key={item.ItemKey} className="items-list-item">{item.Title}</li>)
      })
    } </ul>
  )
}

ReactDOM.render(<Parent />, document.getElementById("app"));
&#13;
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>

<div id="app"></div>
&#13;
&#13;
&#13;

答案 2 :(得分:1)

如果您使用的是redux,这是一个非常简单的解决方法,但如果您不是:

当组件安装时,它会立即搜索props.items,但它是null。您有一个最终获取数据的异步事件,但它的执行速度不够快。

解决此问题的最简单方法是在组件尝试呈现内容之前使用条件语句控制.map接受的内容。

function ItemGrid (props){
    const items = props.items ? props.items : []
    return (
        <ul className='items-list'>
            {items.map(function(item, index){
                <li key={item.Title} className="items-list-item">
                </li>
            })}
        </ul>
    )
}

检查props.items是否为null。如果是,则渲染一个空数组,这样它就不会抛出错误。如果确实存在,则使用props.items

请注意,这只有在收到数据数据后进行重新渲染尝试时才有效。我个人会使用promises和state来控制渲染,因为这可以在任何情况下使用。它是一个更加复杂的解决方案,但是作为React开发人员,您应该知道这些内容就像手背一样。让我们更新。