循环通过对象React

时间:2017-08-13 16:52:51

标签: javascript reactjs ecmascript-6 jsx

我的React组件具有以下渲染

componentWillMount () {
    var url = 'https://gist.githubusercontent.com/hart88/198f29ec5114a3ec3460/raw'
    Request.get(url)
    .then(data => {
        this.setState({cakes: data.text});
    })
}

render() {
    return(
        <div>
            {this.state.cakes} //prints this ok

            {
              this.state.cakes.map(cake =>{ // error here
                return <p>{cake.title}</p>;
              })
            }
        </div>
    );
}

我试图遍历this.state.cakes,这是一个对象数组。

我在这里做错了什么?

更新 - this.state.cakes的缩写示例:

[
    {
        "title": "Lemon cheesecake",
        "desc": "A cheesecake made of lemon",
        "image":"https://s3-eu-west-1.amazonaws.com/s3.mediafileserver.co.uk/carnation/WebFiles/RecipeImages/lemoncheesecake_lg.jpg"
    },
    {
        "title":"Banana cake",
        "desc":"Donkey kongs favourite", 
         "image":"http://ukcdn.ar-cdn.com/recipes/xlarge/ff22df7f-dbcd-4a09-81f7-9c1d8395d936.jpg"
    }
]

由于

4 个答案:

答案 0 :(得分:1)

我相信你已经使用了花括号(可以理解),其中React实际上需要括号。由于您从fetch获取数据,因此请务必使用初步cakes对象设置构造函数。试试这个:

constructor(props) {
    super(props)
    this.state = {
        cakes: []
    }
}

render() {
    if (this.state.cakes.length > 0){
        return(
            <div>
                {
                    this.state.cakes.map(cake => (
                        return <p>{cake.title}</p>;
                    ))
                }
            </div>
        );
    }

    return null
}

问题是该组件正在呈现,并且您告诉它使用名为this.state.cakes的数组执行某些操作,但this.state.cakes尚未定义,因为fetch没有还没回来。像这样设置你的构造函数会将一个空数组传递给render,这样它就不会被吓坏,然后当你的数据加载并且状态更新时,它会重新呈现你的数据。

{this.state.cakes}本身就是正常渲染的原因是因为对于组件存在的第一个瞬间,该值为undefined,这意味着React基本上只是忽略它 - 一次加载的数据,它呈现。但是,map方法失败,因为您无法将未定义的数组传递到map

正如Ha Ja建议的那样,您应该为key元素添加<p>属性。

答案 1 :(得分:1)

下面:

{this.state.cakes.map((cake, i) => <p key={i}>{cake.title}</p>;)}

不要忘记添加key属性。 Ps:最好使用唯一的Id而不是数组索引。因此,如果每个数组项都有一个id,那么最好写一下:

{this.state.cakes.map(cake => <p key={cake.id}>{cake.title}</p>;)}

答案 2 :(得分:1)

如果将状态设置为fetch的resutl,则由于异步操作,您可能无法立即访问数据。您可以通过检查状态来捕获它,如果它没有长度,则返回一条消息或一个微调器组件来指示数据正在运行。

使用fetch操作中的数据更新state.cakes后,组件将重新渲染。

constructor(props) {
  super(props);
  this.state = { cakes: [] };
}

componentDidMount() {
  fetch('/cakes')
    .then(res => res.json())
    .then(cakes => this.setState({ cakes }));
}

render() {
  if (!this.state.cakes.length) return <Spinner />
  return (
    <div>
      {this.state.cakes.map(cake => {
        return <p>{cake.title}</p>;
      })};
    </div>
  )
}

正如其他人所说,将keys添加到迭代元素中也是一种好习惯。

答案 3 :(得分:0)

您错过了map

内的括号
    {this.state.cakes.map(cake =>{ // errors here
        return <p> {cake.title} </p>;
    })}