我在对象内部有一个包含对象的数组。 我可以用console.log记录第一个对象和数组,但是当我尝试访问数组中的对象或在数组上使用map函数时,出现一个错误,提示“无法读取未定义的属性”。>
我已经在SO和其他站点中进行了彻底的搜索以查找类似的问题,并发现了一些但没有答案的解决方案。
对象看起来像这样:
{
answers: [{…}],
createdAt: "2019-01-23T10:50:06.513Z",
nested: {kebab: "jjjj", sås: 2, sallad: "kkk"},
text: "weaxcc",
/* etc... */
}
我可以使用this.state.data
我想访问答案数组内的对象,如:
this.state.data.answers[0].text
甚至:
this.state.data.answers.map().....
但是,这使我无法读取未定义的属性“ 0”。答案数组不能为空。
感谢您的帮助!
编辑 这就是对象最终处于我的状态的方式。
getQuestionFromDb = () => {
axios.get(`http://localhost:3000/questions/${this.state.id}`)
.then(res => this.setState({
data: res.data
}));
};
此函数在ComponentDidMount()方法中调用。
这是我的渲染功能(console.log导致错误):
render() {
return (
<div className="main-content">
<h2>{this.state.data.text} </h2>
{console.log(this.state.data.answers[0].text)}
<p>Introducing <strong>{this.state.id}</strong>, a teacher who loves teaching courses about <strong>{this.state.id}</strong>!</p>
<input
type="text"
onChange={e => this.setState({ message: e.target.value })}>
</input>
<button onClick={() => {this.handleAnswerPost(this.state.message)}}>Answer</button>
</div>
);
}
}
答案 0 :(得分:1)
当第一次安装组件时数据中不包含answers[]
时,这可能不起作用。
您可能要检查阵列的存在,如下所示:
const { data } = this.state;
data.hasOwnProperty('answers') && console.log(data.answers[0]);
答案 1 :(得分:1)
componentDidMount
,但是由于XHR,填充状态所用的调用是异步的,因为XHR可能需要100-300ms的时间才能在组件中获取数据,因此this.state.data.answers
在最初的render()
周期中将不可用。
由于您提到使用循环,所以建议设置初始状态形状,例如
this.state = {
data: {
answers: []
}
}
您的初始渲染将不会有任何循环,但是只要它解析了数据并设置了新状态,它就会正确渲染。
或者您可以
return this.state.data.answers.length ? loopItemsHere : <div>Loading..</div>
很显然,loopItemsHere
可以是您为显示答案而编写的任何内容。
答案 2 :(得分:0)
之所以我们无法访问Javascript中的对象键,通常是因为变量/值不是对象的类型。请确保console.log( typeof this.state.data )
类型为Object。您可以尝试object
。我们应该期望它是输出string
。如果类型为JSON.parse()
,则应首先使用{{1}}对其进行解析。
答案 3 :(得分:0)
有很多原因可能导致数据对象不显示:
对象在被调用时尚未处于状态。这可能是由于异步运算符未加载数据所致。例如。如果您要从数据库中请求对象,则可能是在调用检索数据(this.state.data
)时未给出响应。
该对象可能尚未解析为字符串。尝试运行console.log(typeof this.state.data)
。如果输出为string
,则可能必须解析它。如果输出为undefined
,则第一点有效