我的React组件具有以下渲染
componentWillMount () {
var url = 'https://gist.githubusercontent.com/hart88/198f29ec5114a3ec3460/raw'
Request.get(url)
.then(data => {
this.setState({cakes: data.text});
})
}
render() {
return(
<div>
{this.state.cakes} //prints this ok
{
this.state.cakes.map(cake =>{ // error here
return <p>{cake.title}</p>;
})
}
</div>
);
}
我试图遍历this.state.cakes,这是一个对象数组。
我在这里做错了什么?
更新 - this.state.cakes
的缩写示例:
[
{
"title": "Lemon cheesecake",
"desc": "A cheesecake made of lemon",
"image":"https://s3-eu-west-1.amazonaws.com/s3.mediafileserver.co.uk/carnation/WebFiles/RecipeImages/lemoncheesecake_lg.jpg"
},
{
"title":"Banana cake",
"desc":"Donkey kongs favourite",
"image":"http://ukcdn.ar-cdn.com/recipes/xlarge/ff22df7f-dbcd-4a09-81f7-9c1d8395d936.jpg"
}
]
由于
答案 0 :(得分:1)
我相信你已经使用了花括号(可以理解),其中React实际上需要括号。由于您从fetch
获取数据,因此请务必使用初步cakes
对象设置构造函数。试试这个:
constructor(props) {
super(props)
this.state = {
cakes: []
}
}
render() {
if (this.state.cakes.length > 0){
return(
<div>
{
this.state.cakes.map(cake => (
return <p>{cake.title}</p>;
))
}
</div>
);
}
return null
}
问题是该组件正在呈现,并且您告诉它使用名为this.state.cakes
的数组执行某些操作,但this.state.cakes
尚未定义,因为fetch
没有还没回来。像这样设置你的构造函数会将一个空数组传递给render
,这样它就不会被吓坏,然后当你的数据加载并且状态更新时,它会重新呈现你的数据。
{this.state.cakes}
本身就是正常渲染的原因是因为对于组件存在的第一个瞬间,该值为undefined
,这意味着React基本上只是忽略它 - 一次加载的数据,它呈现。但是,map
方法失败,因为您无法将未定义的数组传递到map
。
正如Ha Ja建议的那样,您应该为key
元素添加<p>
属性。
答案 1 :(得分:1)
下面:
{this.state.cakes.map((cake, i) => <p key={i}>{cake.title}</p>;)}
不要忘记添加key
属性。
Ps:最好使用唯一的Id而不是数组索引。因此,如果每个数组项都有一个id,那么最好写一下:
{this.state.cakes.map(cake => <p key={cake.id}>{cake.title}</p>;)}
答案 2 :(得分:1)
如果将状态设置为fetch的resutl,则由于异步操作,您可能无法立即访问数据。您可以通过检查状态来捕获它,如果它没有长度,则返回一条消息或一个微调器组件来指示数据正在运行。
使用fetch操作中的数据更新state.cakes
后,组件将重新渲染。
constructor(props) {
super(props);
this.state = { cakes: [] };
}
componentDidMount() {
fetch('/cakes')
.then(res => res.json())
.then(cakes => this.setState({ cakes }));
}
render() {
if (!this.state.cakes.length) return <Spinner />
return (
<div>
{this.state.cakes.map(cake => {
return <p>{cake.title}</p>;
})};
</div>
)
}
正如其他人所说,将key
s添加到迭代元素中也是一种好习惯。
答案 3 :(得分:0)
您错过了map
{this.state.cakes.map(cake =>{ // errors here
return <p> {cake.title} </p>;
})}