在App.js
我有一个组件,我传递了一些道具:
<Populated
addressParts={this.state.info}
/>
this.state.info
是一个包含其他对象的对象:
title: 'blahblahblah'
details: Array(3)
......等等......
details
包含以下字段:
name: 'this is a question'
levelOfDifficulty: 100000
......等等......
我的代码如下:
import React from 'react'
class Populated extends React.Component {
render() {
return(
<h1>{this.props.addressParts.title}</h1>
)
}
}
export default Populated
但是,即使我尝试console.log this.props.addressParts.details [0] .name,我也会收到以下错误:
TypeError: undefined is not an object (evaluating 'this.props.addressParts.details[0]')
我在这里做错了什么?我是否需要以某种方式将道具映射到初始状态?提前谢谢。
答案 0 :(得分:0)
假设您正在正确传递道具,您将收到错误,因为该组件在数据获取之前呈现并尝试访问this.props.addressParts.details[0]
。为了避免抛出错误,您可以将它放在导致错误的组件的render方法的最顶层:
if (!this.props.addressParts) return null;
获取数据并更新道具后,组件将重新渲染。
如果_.get(this.props, 'addressParts.details[0]')
未定义,您还可以使用lodash this.props.addressParts
返回undefined而不是抛出错误。
答案 1 :(得分:0)
您没有在第一次渲染调用中提供道具,因为您在异步获取数据后设置状态。
您可以在Populated
组件内或App
组件内执行conditional rendering。
以下是您的代码的运行代码段,请注意您必须将info
启动为null,以便我所做的当前条件能够正常运行。你可以用其他方式和其他条件来做,这只是其中之一。
class Populated extends React.Component {
render() {
const { addressParts } = this.props || {}; // just in case you want do defualt to an empty object
return (
<div>
<h1>{addressParts.title}</h1>
<h2>{addressParts.details.name}</h2>
<h3>{addressParts.details.levelOfDifficulty}</h3>
</div>
)
}
}
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
// you must initilize info to null so the current condition will work
info: null
}
}
componentDidMount() {
// just mimic an async fetch here
setTimeout(() => {
this.setState({
info: {
title: 'im here',
details: {
name: 'this is a question',
levelOfDifficulty: 100000
}
}
})
}, 1200);
}
render() {
const { info } = this.state;
return (
<div>
{
info ?
<Populated addressParts={this.state.info} /> :
<div>Loading data...</div>
}
</div>
);
}
}
ReactDOM.render(<App />, document.getElementById('root'));
&#13;
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="root"></div>
&#13;