reactjs - FlatList 未使用 React Hooks 和 Realm 更新
问题描述
我正在编写一个自定义钩子以将其与realm-js一起使用。
export default function useRealmResultsHook<T>(query, args): Array<T> {
const [data, setData] = useState([]);
useEffect(
() => {
function handleChange(newData: Array<T>) {
// This does not update FlatList, but setData([...newData]) does
setData(newData);
}
const dataQuery = args ? query(...args) : query();
dataQuery.addListener(handleChange);
return () => {
dataQuery.removeAllListeners();
};
},
// eslint-disable-next-line react-hooks/exhaustive-deps
[query, ...args]
);
return data;
}
在我的组件中:
const MyComponent = (props: Props) => {
const data = useRealmResultsHook(getDataByType, [props.type]);
return (
<View>
<Text>{data.length}</Text>
<FlatList
data={data}
keyExtractor={keyExtractor}
renderItem={renderItem}
/>
</View>
);
};
在前面的组件中,当执行 时setData(newData)
,data.length
在Text
. 但是,FlatList
不会重新渲染,就像数据没有改变一样。
我之前使用了一个 HOC 和一个具有相同行为的渲染道具,它按预期工作。难道我做错了什么?我想避免克隆数据setData([...newData]);
,因为这可能是大量数据。
编辑 1
回购以重现它
https://github.com/ferrannp/realm-react-native-hooks-stackoverflow
解决方案
处理程序中的初始data
变量和newData
arg 是指向同一集合的链接。所以它们是相等的,setData(newData)
在这种情况下不会触发组件的重新渲染。
将 Realm 集合映射到项目 ID 数组可能会有所帮助。因此,您将始终拥有处于 React 状态的新数组,并且渲染将正确进行。仅检查集合的删除和插入以避免列表的额外重新呈现也很有用。但在这种情况下,您还应该向项目添加侦听器。
function useRealmResultsHook(collection) {
const [data, setData] = useState([]);
useEffect(
() => {
function handleChange(newCollection, changes) {
if (changes.insertions.length > 0 || changes.deletions.length > 0) {
setData(newCollection.map(item => item.id));
}
}
collection.addListener(handleChange);
return () => collection.removeListener(handleChange);
},
[]
);
return data;
}
推荐阅读
- javascript - 避免在使用不受支持的 HTML 功能时产生错误
- java - sdkmanager 返回相同的输出,而不管传递给它的参数是什么
- kubernetes - 如何使用 kubectl 标签重新标记 k8s 中的多个 pod?
- typescript - 用 setTimeout 承诺
- python-3.x - pd.to_sql 返回 KeyError: '\x02' on Windows Server 2008 R2 (Python 3.6.4) (Pandas 0.25)
- sqlite - Xamarin MVVM 从另一个页面删除 Listview 项目
- android - 如何进行这样的对话?
- apache-spark - Spark 中的用户定义函数 (UDF) 是否在集群工作节点上并行运行?
- python - 与文件系统交互
- google-analytics - 使用数据层和 Google 跟踪代码管理器跟踪结帐行为