映射数组处于状态错误,' Warning: Encountered two children with the same key '



我的react原生应用程序会填充用户相册列表,显示一些图像和相册的关键信息。

最初,我遍历每个相册,将必要的数据推送到一个新的数组中。完成后,我将此数组设置为state,并通过FlatList显示它。这很好,没有任何错误,但问题是加载时间很长,因为在向用户显示任何内容之前,您必须等到检索到所有相册的信息。

因此,我选择了将包含相册信息的每个新对象推送到状态中的数组中。这样,一个相册将在检索到后立即显示,而不是等待加载所有其他相册。代码如下(为了便于说明,简化代码(:

const [albums, setAlbums] = useState([])
const getAllAlbums = async () => {

//iterate over each album and call api to retrieve necessary information
setAlbums(prevState => [...prevState, {
albumName: 'xyz',
numberOfPhotos: 'xyz',
previewImage:'xyz',
...etc
}]
}

然后我返回一个平面列表,它看起来像这样(为了简单起见,省略了样式(:

<FlatList 
data={albums}
key={2}
renderItem={({item, index})=>{
return (
<Pressable key={index} onPress={//do something}>
<View>
<Image source = {{uri: item.preview}}/>
<Text>{item.title}: {item.assetCount} imgs</Text>
</View>    
</Pressable>
)
}}
keyExtractor={(item)=>item.id}
/>

代码工作,相册显示。但出于某种原因,我一直收到这样的信息:

警告:遇到两个具有相同密钥BBD020CF-7E5C-412D-BA1A-D9C12ACAD91A:ACF588A8-A07E-4DD4-ADC2-E12BB0A1BCF3的子级。密钥应该是唯一的,以便组件在更新过程中保持其身份。非唯一密钥可能会导致子项被重复和/或省略——这种行为不受支持,并且可能在未来版本中发生更改。

向用户显示的内容似乎存在重复。不是一次检索专辑列表(即,专辑1、专辑2、专辑3、专辑4(,而是输出似乎重复/重复了几次(即,相册1、专辑二、专辑三、专辑四、专辑一、专辑二和专辑三、相册四、专辑1、相册二、专辑3和专辑4(。

这显然是问题的原因,但我不知道为什么会发生这种情况。非常感谢您的建议。谢谢

编辑完整的getAllAlbums功能在这里:


useEffect(async()=>{
const getAllAlbums = async () => {
//retrieve all album
const getAlbums = await MediaLibrary.getAlbumsAsync({includeSmartAlbums: true})
//filter out empty albums    
const albumsWithPhotos = getAlbums.filter((item)=>{
return item.assetCount>0
})

for(let i=0; i<albumsWithPhotos.length; i++){
//get the most recent photo in the album to use as cover
const mostRecentPhoto = await MediaLibrary.getAssetsAsync({album: albumsWithPhotos[i].id, mediaType: 'photo', first: 1})
//prevent crashes 
if (typeof(mostRecentPhoto.assets[0]) == 'undefined'){
continue;
}
//get the local uri needed by image component
const updatedPhoto = await MediaLibrary.getAssetInfoAsync(mostRecentPhoto.assets[0].id)
if(updatedPhoto){
const compressedImage = await ImageManipulator.manipulateAsync(updatedPhoto.localUri, [], { compress: 0.1 });
//add album to state array
setAlbums(prevState => [...prevState, {
title: albumsWithPhotos[i].title,
assetCount: albumsWithPhotos[i].assetCount,
id: albumsWithPhotos[i].id,
preview: compressedImage.uri 
}])      
}
}
}
const result = await getAllAlbums()

}, [])

您可以使用您的url作为密钥。

这种行为的原因是它迭代并重新渲染您添加的相册的最后一部分,而不是全部相册。因此,再次从0开始计数,导致重复的键。

<Pressable key={index} onPress={//do something}><--这里传递的密钥是多余的,只要你使用FlatListkeyExtractor就足够了,可以完成的工作

++

不建议使用index作为key

您应该通过传递一个区分列表中每个项目的真实密钥来帮助FlatList渲染每次渲染才更改的项目

因此,请尝试使用id,或列表中您确信每个列表项唯一的任何其他字段

相关内容

最新更新