通过点表示法遍历范围内的JSON对象时遇到React错误

时间:2019-03-24 03:58:48

标签: javascript json reactjs

render() {
    return (
        <p>{this.state.recipes[0].title}</p> // This is what I believe should work - Ref Pic #1
        // <p>{this.state.recipes[0]}</p>    // This was trying random stuff to see what happens - Ref Pic #2
        // <p>{this.state.recipes.title}</p> // This was me trying crazy nonsense - Ref Pic #3
    )
}

我试图遍历一些JSON,并得到一些非常奇怪的响应。如果有人想亲自看一下JSON,可以在this link上找到它。

运行第一个p标签时,我得到以下响应: This is my first question, so I can't embed images, I'm sorry.

不确定为什么配方[0]未定义,我再次用第二个p标签soley对其进行了注释,但得到了以下响应:Still the same question, still can't embed, sorry again.

该响应确实使我措手不及,因为它所引用的键(nid,title等)是我知道对象中的键。我想要的是“标题”。

最后,我只尝试了第三个p标签,该应用程序实际上已编译到第三个p标签,没有错误,但是p标签为空。 Here's what I have in React Devtools, but I still can't embed.

查看<食谱>,它清楚地表明状态完全符合我想要的状态,图二显示了食谱[0]具有我第一次尝试调用的键。我已经搜索并搜索过Google,甚至将自己的亲人都当作橡皮鸭,但无济于事。

我在做什么错了?

3 个答案:

答案 0 :(得分:0)

您可以执行以下操作来处理有数据和无数据时的状态

constructor(props) {
      super(props);

      this.state = {
        recipes: []
      };
    }


 render() {
             return (
                 <p>
                  {this.state.recipes && this.state.recipes.length ? {this.state.recipes[0].title} : {this.state.recipes}}       
                </p> 
             )
         }

答案 1 :(得分:0)

第一个p标签中的错误告诉您确切的情况。访问“未定义”的属性会破坏javascript / react。

您可能一定没有状态中的预期数据,以验证我的意思,只需在渲染器中通过console.log(this.state)进行调试即可:

render() {
  console.log(this.state); // probably has this.state.recipes empty array at first render
  ...

这可能是由于api的异步调用填充了您的状态而导致的。在您从api发出的异步请求得到解决之前,将首先调用渲染(这意味着很遗憾,您还没有处于状态的..recipes [0]数据)

我猜你的componentDidMount中有这个东西:

componentDidMount() {
  ThirdParty.fetchRecipes().then(data => {
     this.setState({ recipes: data.recipes }); // after setState react calls render again. This time your p tag should work.
  })
  ...

如果您有较新的React版本,建议您使用可选链接,因为您感兴趣的属性是深层嵌套的:How to handle calling functions on data that may be undefined?

<p>{this.state?.recipes?.[0]?.title}</p>

另一种有效方法,但过于冗长:

const title =
  this.state &&
  this.state.recipes &&
  this.state.recipes.length &&
  this.state.recipes[0].title
    ? this.state.recipes[0].title
    : "";

render() {return (<p>{title}</p>)}

答案 2 :(得分:0)

我相信您正在异步获取JSON。在这种情况下,您应考虑初始配方状态为空数组的边界情况。

  1. 运行第一个p标签时,由于JSON是异步获取的,因此最初未定义this.state.recipes,因此会收到错误。

  2. 运行第二个p标签时,在第一次渲染期间,this.state.recipes是未定义的,因此它可以在p标签中使用,但是在获取JSON并声明状态之后设置后,渲染又被调用,这次this.state.recipes[0]是一个对象,因此不能算作有效的React组件,因此会出现错误。

  3. 使用第三个p标签,就像您自己提到的那样,this.state.recipes.title将成功编译且没有错误,但是该值是不确定的。

您只需要检查初始状态为空的边缘情况。

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

        render() {
             return (
                 <p>
                  {this.state.recipes.length > 0 ? {this.state.recipes[0].title} : ''}       
                </p> 
             )
         }