无法在React中访问嵌套的JSON对象

时间:2018-05-18 19:14:01

标签: javascript json reactjs

我有一个简单的React组件,我试图在render中显示嵌套的JSON对象。

// React Component

class NodeDetail extends React.Component {
  constructor(props) {
    super(props);
    const node = {};

    this.state = {
      node
    }
  }

  componentDidMount() {
    Node.getNode(this.props.node_id).then((result) => {
      console.log(result.data);
      this.setState(() => ({node: result.data}));
    }).catch(function(error) {
      // TODO: handle error
    });
  }

  render() {
    return (
      <div>
        {this.state.node.node_status.name}
      </div>
    );
  }
};

export default NodeDetail;

这是从rails API返回的JSON(存储在result.data中)(为简洁起见,删除了一些字段):

{  
   "id":1234,
   "name":"some-node",
   "created_at":"2018-05-18T15:23:24.012Z",
   "hostname":"some-host",
   "ip":"10.XXX.XXX.XXX",
   "mac":"24:6e:96:XX:11:XX",
   "node_status":{  
      "id":2,
      "name":"Parked"
   }
}

当我使用this.state.node.mac访问React中的根级别属性时,它会返回24:6e:96:XX:11:XX

当我尝试使用name访问node_status中的this.state.node.node_status.name属性时,出现以下错误:

Uncaught TypeError: Cannot read property 'name' of undefined

我也尝试了this.state.node['node_status'].name,同样的错误。

为什么我不能在JSON中访问这个对象,当它明显存在时?

4 个答案:

答案 0 :(得分:4)

我敢打赌,因为你对Rails API的调用是异步的 - 所以你的NodeDetail组件在API返回之前尝试渲染数据/状态是用result.data设置的。正如其他一些答案所暗示的那样,.try为不存在的node_status提供条件。

所以当前(错误的)数据流将是:

  1. constructorstate设置为{node: {}}
  2. componentDidMount。调用API。
  3. render。引发异常,因为this.state.node.node_statusundefined。组件中断并且不会再次渲染......
  4. API返回。 state设置为result.dataresult.data会被记录到您的控制台。
  5. 你可以做的是:

    render() {
        if (!this.state.node.node_status) {
          return null;
        }
    
        return (
          <div>
            {this.state.node.node_status.name}
          </div>
        );
      }
    

    或考虑undefined的{​​{1}}值的任何其他建议。

    一般情况下,即使this.state.node.node_status中设置了默认render值,您也需要确保state方法有效。

答案 1 :(得分:2)

错误正确无误您在加载组件后提取data简而言之,您在componentDidMount中调用了API 你可以用这种方式摆脱这个错误

 <div>
        {this.state.node.node_status?this.state.node.node_status.name:""}
 </div>

我建议您在componentWillMountconstructor中调用抓取数据API,这是component的初始阶段。

答案 2 :(得分:1)

唯一对我有用的解决方案:https://stackoverflow.com/a/51175467

问题是 JSON 对象可以在填充之前访问一级深度,因此在您尝试访问嵌套属性之前它不会破坏您的网页。

答案 3 :(得分:0)

渲染中

newsapi_news.spacy_tags[object object]

newsapi_news.spacy_tags.all_tags THROWS无法读取未定义错误的道具

但这会起作用

data-tag={(newsapi_news.spacy_tags) ? newsapi_news.spacy_tags.all_tags : ""}

渲染器中的代码必须“编译”或装入,或使用任何术语,并且父元素尚未定义,但父元素的父元素是