在 React 类中,我调用了一个需要参数的函数:
renderColumnChart(chart) {
console.log('rendering chart');
console.log(typeof chart); // <<<<<<<< OK! I get "Object"
console.log(chart); // <<<<<<<<<<<<<<< OK! I get the object in the console
console.log(chart.title); // <<<<<<<<< NO! I get the error :(
return (
<React.Fragment>
<br />
<Chart
width={'100%'}
height={'400px'}
chartType="Bar"
loader={<div>Loading Chart...</div>}
data={[
['City', '2010 Population', '2000 Population'],
['New York City, NY', 8175000, 8008000],
['Los Angeles, CA', 3792000, 3694000],
['Chicago, IL', 2695000, 2896000],
['Houston, TX', 2099000, 1953000],
['Philadelphia, PA', 1526000, 1517000],
]}
options={{
chart: {
title: 'Chart Title',
subtitle: 'Hello World',
},
legend: { position: 'none' },
chartArea: { width: '50%' },
hAxis: {
title: 'Total Population',
minValue: 0,
},
vAxis: {
title: 'City',
},
}}
/>
</React.Fragment>
);
}
在我的类中render()
函数,我有条件地调用该函数,等待 API 调用
{this.state.isloading ? (
<div>
<h1>Loading...</h1>
</div>
) : (
this.renderColumnChart(this.state.reports[0])
)}
在 API 调用后将isLoading
设置为 false:
componentDidMount() {
this.getData();
this.setState({
isLoading: false,
});
}
但是我收到此错误:Uncaught TypeError: Cannot read property 'title' of undefined
这令人困惑,因为:为什么我可以记录对象而不是它的任何值?
请务必知道,开发者工具中的 Chrome 控制台会显示对象的"实时"(即扩展时的当前)视图。
请尝试以下实验。将以下代码复制并粘贴到 Chrome 的控制台中:
const obj = {};
console.log(obj);
obj.foo = 'bar';
setTimeout(() => obj.bar = 'baz');
最初,它将显示为▶ {}
,但如果您展开它,它将显示它有两个属性,foo
和bar
,这两个属性都是在记录对象后添加的。
在记录对象时的状态记录对象的唯一可靠方法是创建它的(深层)副本。一种方法是使用JSON.parse(JSON.stringify(obj))
,假设整个对象都可以序列化为 JSON。
关于您的问题,如果您的代码与您的问题中的代码完全相同,则有一种可能性,那就是您在render()
函数中的引用中有拼写错误,以this.state.isloading
何时应该this.state.isLoading
。
但我怀疑这不是真正的问题。我怀疑正在发生的事情是在初始渲染期间,如果您正在初始化this.state = { reports: [], ...etc... }
,则this.state.reports[0]
的值是undefined
。然后,在getData()
异步完成后,您将更新状态,因此this.state.reports = [{ title: 'Foo', ...etc... }]
有效地。当 React 再次调用render()
时,它可以看到完整的对象。
最后,正如其他人所说,由于getData()
是异步的,因此您需要在设置reports
状态时或之后将this.setState({ isLoading: false })
移动到getData()
函数中。或者,如果可以使用async / await
构造,getData()
设置为异步,然后componentDidMount()
变为:
async componentDidMount() {
await this.getData();
this.setState({ isLoading: false });
}
在收到来自 API 调用的响应后,将isLoading: false,
添加到getData
内,将其从componentDidMount
中删除
componentDidMount() {
this.getData();
//this.setState({
// isLoading: false,
//});
}