在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
困惑的原因是:为什么我可以记录对象但不能记录其任何值?
答案 0 :(得分:1)
重要的是要知道开发人员工具中的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[0]
,则undefined
的值为this.state = { reports: [], ...etc... }
。然后,getData()
异步完成后,您正在更新状态,因此this.state.reports = [{ title: 'Foo', ...etc... }]
有效。当React再次调用render()
时,它可以看到完整的对象。
最后,正如其他人所说,由于getData()
是异步的,因此在设置this.setState({ isLoading: false })
状态时或之后,需要在getData()
函数内部移动reports
。另外,如果可以使用async / await
构造,请使getData()
异步,然后componentDidMount()
变为:
async componentDidMount() {
await this.getData();
this.setState({ isLoading: false });
}
答案 1 :(得分:0)
在t2>t1
内添加isLoading: false,
,将其从getData
删除
componentDidMount