我有一个JSON DB和一个React组件来获取这些数据。 这是我的JSON DB:
{
"houses": [
{
"id": 1,
"name": "house 1"
},
{
"id": 2,
"name": "house 2"
},
{
"id": 3,
"name": "house 3"
}
]
}
它是由ReactJS组件获取的。当我在Axios的循环中执行console.log()时,它可以成功运行。但是在render方法内部,它不起作用。我该如何解决?
class Houses extends Component {
constructor(props) {
super(props);
this.state = {
index:0,
currentHouse:[]
};
}
componentDidMount() {
axios.get(URL_HOUSES)
.then(res => {
this.setState({ index:0 })
this.setState({ currentHouse: res.data})
//Here is working! It is returning the index and the current house's name
console.log('index:' + this.state.index)
console.log(
'Name of the current house:' +
this.state.currentHouse[this.state.index].name
)
}
render() {
return (
<div>
//Here isn't working. It is returning an error message:
//TypeError: Cannot read property '0' of undefined
<h3>{this.state.currentHouse[this.state.index].name}</h3>
</div>
);
}
}
export default Houses
答案 0 :(得分:1)
TL; DR在渲染方法中显示它之前先检查currentHouse初始数组。
在组件的初始呈现中,currentHouse
数组中没有元素。
因此,当您的组件尝试打印您的语句this.state.currentHouse[this.state.index].name
时,实际上要执行的操作是找到空数组[]
的第0个位置。 这将评估为 undefined
。
解决此问题的选项是在状态下为currentHouse数组设置初始值,或检查数组中是否有值。例如:
<h3>{this.state.currentHouse.length && this.state.currentHouse[this.state.index].name}</h3>
答案 1 :(得分:0)
此错误的原因是render()
方法试图在数据可用之前呈现数据。请尝试以下解决此问题:
class Houses extends Component {
constructor(props) {
super(props);
this.state = {
index:0,
currentHouse:[]
};
}
componentDidMount() {
axios.get(URL_HOUSES)
.then(res => {
/* Combine into single setState call (this is optional, but
makes for cleaner code. Note that calling setState will
trigger the component to render() again, which will cause
your currentHouse[0].name to be rendered into <h3> below */
this.setState({ index:0, currentHouse: res.data })
}
render() {
/* Detect if currentHouse data is ready/avalible - if not, render
a temporary loading message */
if(this.state.currentHouse.length === 0) {
return <p>Loading</p>
}
/* If we reach this point, then there is data in this.state.currentHouse
that can be accessed and rendered */
return (
<div>
<h3>{this.state.currentHouse[this.state.index].name}</h3>
</div>
);
}
}
export default Houses