【问题标题】:Loop through objects React循环遍历对象 React
【发布时间】:2017-08-13 16:52:50
【问题描述】:

我的 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"
    }
]

谢谢

【问题讨论】:

  • 您遇到的错误是什么?
  • 您能打印出Cakes 数组中的内容吗?因为如果它是对象数组(这在这里似乎最明显)。然后错误出现在 `{this.state.cakes}` 行而不是另一行。
  • @MinkeshJain 更新了 {this.state.cakes},
  • 如何将数据加载到状态中?是否使用来自服务器的fetchmap 未定义,因为 cakes 还不是数组,这意味着组件无法使用数据。
  • @Spdexter - state.cakes 如何在您的组件构造函数中定义?您提供的示例是硬编码的,还是像 @Andy 建议的那样,是 fetch 的结果?

标签: javascript reactjs ecmascript-6 jsx


【解决方案1】:

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

一旦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 添加到您的迭代元素中也是一种很好的做法。

【讨论】:

  • 谢谢!我明白你所说的并应用了。我现在得到加载几秒钟,然后得到这个错误:未处理的拒绝(TypeError):this.state.cakes.map is not a function :(
  • 将获取操作的代码添加到您的问题或 jsfiddle 中,我会看看。
  • @Spdexter,我添加了一些示例获取代码。你的和那个很像吗?
  • 这是我的 componentWillMount () { var url = 'gist.githubusercontent.com/hart88/198f29ec5114a3ec3460/raw' Request.get(url) .then(data => { this.setState({cakes: data.text}); } ) }
  • 由于某种原因,我无法让 .json() 与 Superagent 一起使用,替换为 Fetch 并且它运行良好 - 感谢您的帮助!
【解决方案2】:

这里:

{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>;)}

【讨论】:

    【解决方案3】:

    我相信你在 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 属性添加到 &lt;p&gt; 元素。

    【讨论】:

    • 嗨,谢谢@skwidbreth,它没有用 - 我得到的错误是无法读取未定义的属性“地图”!
    • cakes 还不是数组。添加其余的组件代码@Spdexter,这样我们就可以看到你的状态是如何用你的 JSON 填充的。
    • 呃,你怎么能得到打印this.state.cakes的结果,但在下一行代码中有cakes作为undefined。你确定cakes 是一个数组吗?
    • 你是如何在构造函数中定义state.cakes的?
    • 啊,是的,您需要有条件地渲染它 - 请参阅我更新的答案。
    【解决方案4】:

    您错过了map 中的括号

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-06-09
      • 1970-01-01
      • 2020-04-30
      • 2017-06-12
      • 2015-10-31
      • 2014-11-30
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多