问题描述
我在React / NextJS中使用 .map() 渲染对象时遇到麻烦。
我具有从Firebase Cloud Storage获取图像的功能,如下代码:
getimages = () => {
let firebase = loadFirebase()
var storageRef = firebase.storage().ref('chest')
let { state } = this
storageRef.listAll().then((result) => {
let data = []
result.items.forEach((imageRef) => {
imageRef.getDownloadURL().then((url) => {
data.push(url)
}).catch((error) => {
// Handle any errors
})
})
state.images = data
this.setState({ images: data })
}).catch((error) => {
// Handle any errors
})
}
该部分似乎可以正常工作,因为我确实获取了数据并更新了状态,结果如屏幕截图所示: Results after setState
然后我使用以下代码映射图像:
{ this.state.images.map((image,index) => {
return (
<img
key={ index }
src={ image }
alt=""
/>
)
})}
在与此相同的页面上,我还有其他地方可以从Firebase获取数据,相应地设置状态,并使用 .map() 渲染对象。在那种情况下,它工作得很好。区别在于,在这些情况下,我使用 getinitialProps() 从Firebase获取我的数据,而从Cloud Storage的数据中获得一个函数, getimages() 函数,该函数在 componentDidMount()
上调用但是在两种情况下,状态都在 componentDidMount() 中设置,最终结果返回到 this.state em>看起来像所附的屏幕截图。
在此方面的任何帮助和/或改进将不胜感激。
解决方法
永远不要手动设置状态值。您应该只在调用setState
之前删除将图像设置为状态的行。该行阻止了渲染,因为在您使用setState
设置状态后,该反应之后无法检测到任何更改:
getImages = () => {
let firebase = loadFirebase()
var storageRef = firebase.storage().ref('chest')
storageRef.listAll().then((result) => {
let data = []
result.items.forEach((imageRef) => {
imageRef.getDownloadURL().then((url) => {
data.push(url);
this.setState({ images: data });
}).catch((error) => {
// Handle any errors
})
});
}).catch((error) => {
// Handle any errors
})
}