React & Objects - TypeError:无法读取未定义的属性“map”
2021-02-19
532
我试图从 Django 数据库中检索对象(电机)列表,并将其存储在我的 MachineTemplate 组件的状态中。
这是组件
export default class MachineTemplate extends Component {
constructor(props) {
super(props);
this.state = {
myName: this.props.match.params.id,
motors: {},
error: "None",
loaded: false
}
this.getMachineDetails = this.getMachineDetails.bind(this);
}
componentDidMount() {
this.getMachineDetails();
}
getMachineDetails = () => {
const requestOptions = {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
name: this.state.myName,
}),
};
fetch("http://127.0.0.1:8000/get-motors", requestOptions)
.then((response) => {
if (response.ok) {
this.setState({ motors: response.data });
} else {
this.setState({ error: "Motors not found." });
}
})
.catch((error) => {
console.log(error);
});
this.setState({loaded: true});
}
render() {
if (this.state.loaded) {
return (
<div>
<h1>{this.state.name}</h1>
<h3>{this.state.error}</h3>
{this.state.motors.map(motor => {
return <Button key = {motor.number}>{motor.number}</Button>
})}
</div>
)
} else {
return(
<div>
<h1>Awaiting machine details...</h1>
</div>
)
}
}
}
这是我收到的错误
TypeError:无法读取未定义的属性“map”
我可以确认提取正确返回了我需要的电机对象列表,这些对象在响应中的格式如下:
0:{number:0,enabled:true,item:“EMPTY”,machine:48
我能够使用不同组件中的简单名称列表使此精确设置正常工作,因此任何帮助都将不胜感激。
2个回答
您在构造函数中将一个空对象分配给 this.state.motors。这就是您收到错误的原因。应该是一个空数组。
Don
2021-02-19
fetch()
是
异步
的。这意味着您不能依赖它在下一个语句之前完成执行:
fetch(/**/);
// ...
this.setState({loaded: true}) // fetch() might not finish executing when this statement is executed
因此,您必须确保在正确的位置设置
loaded
状态变量。查看您的代码,类似这样的代码应该可以工作:
fetch("http://127.0.0.1:8000/get-motors", requestOptions)
.then((response) => {
if (response.ok) {
this.setState({
motors: response.json(), // As suggested by @buzatto
loaded: true
});
} else {
this.setState({ error: "Motors not found." });
}
})
.catch((error) => {
console.log(error);
});
每次 prop 更改时获取
考虑添加
componentDidUpdate
以在 props 更改时使用新数据重新获取并重新渲染您的组件:
componentDidUpdate(prevProps) {
// Typical usage (don't forget to compare props):
if (this.props.match.params.id !== prevProps.props.match.params.id) {
this.setState({loaded: false})
this.getMachineDetails();
}
}
另请查看
useEffect
钩子,它可以简化您的代码,将
componentDidMount
和
componentDidUpdate
的功能合并到
function
中组件:
useEffect(() => {
setState({loaded: false})
getMachineDetails();
}, [props.match.params.id]); // Only re-fetch if props.match.params.id changes
Janez Kuhar
2021-02-19