我有一个空数组传递给我的 flat-list
。
我还使用 useEffect
从服务器获取数据并更新列表。
但是,在使用数据设置数组的新状态后,不会重新渲染 flat-list
。
const [listData, setlistData] = React.useState<Transaction[]>([])
const [dataUpdated, setDataUpdated] = React.useState<boolean>(false)
React.useEffect(() => {
if(route.params.showAllData)
{
fetchTransactions(1, TRANSACTION_PAGE_SIZE, 1)
.then((res: Transaction) => {
console.log(`TransactionsScreen: userEffect [] => fetched ${JSON.stringify(res)}`);
setlistData(prevState => ({...prevState, ...res}));
setDataUpdated(true)
})
.catch(err => {
//TODO: handle error scenerio
ToastAndroid.show(`Failed to fetch transacrions`, ToastAndroid.SHORT)
})
}}, [])
<FlatList
data={listData}
renderItem={item => _renderItem(item)}
ItemSeparatorComponent={TransactionListSeparator}
extraData={dataUpdated} // extraData={listData <--- didn't work either}
keyExtractor={item => item.id.toString()}/>
我尝试将数据数组添加为 extraData
值,但没有成功,我还尝试添加另一个布尔值,通知数据已更新,但也无效。
如何正确地重新渲染 flat-list
?
答案 0 :(得分:1)
我是这样解决的:
useEffect(() => {
setDataUpdated(!dataUpdated);
}, [listData]);
注意:
您直接将 dataUpdated
更新为 true。我不推荐这样做,而是这样做:setDataUpdated(!dataUpdated)
另外确保FlatList
的所有元素都具有唯一键,否则不会不惜一切代价重新渲染
答案 1 :(得分:1)
试试这个,确保你正在返回你的子组件并使用 useEffect 提供依赖数组,你想重新渲染你的组件
const [listData, setlistData] = React.useState<Transaction[]>([])
const [dataUpdated, setDataUpdated] = React.useState<boolean>(false)
React.useEffect(() => {
if(route.params.showAllData)
{
fetchTransactions(1, TRANSACTION_PAGE_SIZE, 1)
.then((res: Transaction) => {
console.log(`TransactionsScreen: userEffect [] => fetched ${JSON.stringify(res)}`);
setlistData(prevState => ({...prevState, ...res}));
setDataUpdated(true)
})
.catch(err => {
//TODO: handle error scenerio
ToastAndroid.show(`Failed to fetch transacrions`, ToastAndroid.SHORT)
})
}}, [listData])
return (
<FlatList
data={listData}
renderItem={item => _renderItem(item)}
ItemSeparatorComponent={TransactionListSeparator}
extraData={dataUpdated} // extraData={listData <--- didn't work either}
keyExtractor={item => item.id.toString()}/>
)
答案 2 :(得分:1)
您不能像以前那样散布阵列。例如,如果您有两个数组。
const arr1 = [1, 2, 3];
const arr2 = [4, 5, 6];
然后像这样传播它们:
const arr3 = { ...arr1, ...arr2 };
结果将是:
{ 0: 4, 1: 5, 2: 6 }
将花括号改为正方形。
setlistData(prevState => ([...prevState, ...res]));
因为您的 FlatList
期望数据是一个数组,而不是一个对象。
答案 3 :(得分:0)
您可以通过将更新的列表作为 extraData 道具(即 extraData={listData}
)传递来强制 flatlist 重新呈现。然而,当使用函数式组件时,一个常见的错误是传递与 prop 相同的列表数据实例。即使列表中的内容或列表的长度发生了变化,这也不会触发重新渲染。 FlatList 认为这是相同的,不会重新渲染。
要触发重新渲染,您必须创建一个全新的列表实例。
例如:
//This update will NOT trigger a rerender
const copy = listData;
copy.push(something)
setListData(copy)
////////
<FlatList extraData={listData}
.....
/>
//This WILL trigger a rerender
const copy = [...listData]
copy.push(something)
setListData(copy)
////////
<FlatList extraData={listData}
.....
/>