我正在关注ReactJS AJAX and APIs tutorial。我在Spring中编写了一个简单的API,然后在http://localhost:8080
上使用了一个React组件来使用该API。该API当前返回以下两项的列表:
[
{brand:"Asus", make:"AAA"},
{brand:"Acer", make:"BBB"}
]
这是我的组件的样子:
import React from 'react';
import ReactDOM from 'react-dom';
import { environment } from '../environment/environment';
export class ComputerList extends React.Component {
constructor(props) {
super(props);
this.state = {
error: null,
isLoaded: false,
items: [
{brand: null, make: null}
]
};
}
componentDidMount() {
fetch("http://localhost:8080/computers")
.then(res => res.json())
.then(
(result) => {
// correctly displays the results
console.log(result);
this.setState({
isLoaded: true,
items: result.items
});
},
(error) => {
this.setState({
isLoaded: true,
error
});
}
)
}
render() {
const { error, isLoaded, items } = this.state;
if(error) {
return(<div>Error: {error.message}</div>);
}
else if(!isLoaded) {
return(<div>Loading...</div>);
}
else if(items) {
console.log(items);
// error here: cannot read property "map" of undefined
// because this.state.items is undefined somehow?
return(
<ul>
{items.map(item => (
<li key={item.make}>{item.brand} {item.make}</li>
))}
</ul>
);
}
}
}
在第24行,成功检索并记录了结果。
但是在第54行,当我尝试将每个结果映射到<li>
项时,会抛出TypeError
是因为items
是不确定的?我遵循了对similar question的回答,在第12行初始化了items
,并在第48行检查了items
,无济于事。
我该如何解决?
答案 0 :(得分:1)
这很可能是由于items
的类型不是数组,这就是为什么map()
方法不会被定义的原因。
对于更健壮的render()
方法,可以将else if(items) {
替换为else if(Array.isArray(items)) {
,这样可以避免出现错误消息:
render() {
const { error, isLoaded, items } = this.state;
if(error) {
return(<div>Error: {error.message}</div>);
}
else if(!isLoaded) {
return(<div>Loading...</div>);
}
else if(Array.isArray(items)) { // <-- update here
console.log(items);
// error here: cannot read property "map" of undefined
// because this.state.items is undefined somehow?
return(
<ul>
{items.map(item => (
<li key={item.make}>{item.brand} {item.make}</li>
))}
</ul>
);
}
}
希望有帮助!
答案 1 :(得分:1)
感谢@DacreDenny的建议:)
第27行:items: result.items
。该行期望响应包含一个名为“ items”的对象。
但是我的API仅返回对象数组。所以我将行更改为
第27行到:items: result
。这会将整个数组保存到state.items
。然后可以对其进行正确的映射和渲染。
答案 2 :(得分:0)
这样做吧。避免在渲染中使用if循环,而应直接使用&&运算符或三元运算符来管理if检查
return(
<ul>
{!isLoaded && <div>Loading...</div>}
{error && !isLoaded && <div>Error: {error.message}</div>)}
{!isLoaded && items && items.map(item => (
<li key={item.make}>{item.brand} {item.make}</li>
))}
</ul>
);
此外,对象中的make键最初包含空值,因此您无法将其分配为键。相反,您可以做的是尝试从后端为数组中的对象生成唯一的ID,或者使用下面的类似方法
return(
<ul>
{items && items.map((item, index) => (
<li key={"key"+index}>{item.brand} {item.make}</li>
))}
</ul>
);
请问我有错字问题,因为我正在用手机应答