我有一个简单的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中访问这个对象,当它明显存在时?
答案 0 :(得分:4)
我敢打赌,因为你对Rails API的调用是异步的 - 所以你的NodeDetail
组件在API返回之前尝试渲染数据/状态是用result.data
设置的。正如其他一些答案所暗示的那样,.try为不存在的node_status
提供条件。
所以当前(错误的)数据流将是:
constructor
。 state
设置为{node: {}}
componentDidMount
。调用API。render
。引发异常,因为this.state.node.node_status
是undefined
。组件中断并且不会再次渲染...... state
设置为result.data
。 result.data
会被记录到您的控制台。你可以做的是:
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>
我建议您在componentWillMount
或constructor
中调用抓取数据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 : ""}
渲染器中的代码必须“编译”或装入,或使用任何术语,并且父元素尚未定义,但父元素的父元素是