已用useCallback和memo仍无法阻止FlatList重复渲染
待办事项APP FlatList重渲染问题排查
我正在开发一门编程课程的待办事项列表APP,技术栈为Firebase Realtime Database、React Native和Expo。目前待办列表渲染及点击复选框标记任务优先级的功能正常,但每次点击单个任务的优先级复选框时,整个FlatList都会重新渲染。
每个任务对象结构如下:
{id: ***, text: ***, priority: ***}
Task组件
该组件包含待办文本和标记优先级的复选框,已用React.memo包裹,仅从父组件传入单个task作为props,但仍会触发全局重渲染。代码片段如下(省略标准导入):
import { CheckBox } from '@rneui/themed'; const Task = ({ item }) => { console.log(item) const { user } = useContext(AuthContext); const onPressPriority = async () => { await update(ref(database, `users/${user}/tasks/${item.id}`), { priority: !item.priority, }); }; return ( <View style={{ flexDirection: 'row', alignItems: 'center', width: '95%' }} > <View style={{ width: '90%' }} > <Text>{item.text}</Text> </View> <View style={{ width: '10%' }} > <CheckBox checked={item.priority} checkedColor="#00a152" iconType="material-community" checkedIcon="checkbox-marked" uncheckedIcon={'checkbox-blank-outline'} onPress={onPressPriority} /> </View> </View> ) } export default memo(Task, (prevProps, nextProps) => { if (prevProps.item !== nextProps.item) { return true } return false })
待办列表父组件
该组件包含渲染Task组件列表的FlatList,通过useEffect监听Firebase数据库变化更新tasks状态。曾尝试将更新优先级的函数用useCallback包裹后传入子组件,但点击复选框时所有列表项仍会重渲染。代码片段如下(省略标准导入):
export default function Home2() { const { user } = useContext(AuthContext); const [tasks, setTasks] = useState([]); useEffect(() => { if (user) { return onValue(ref(database, `users/${user}/tasks`), (snapshot) => { const todos = snapshot.val(); const tasksCopy = []; for (let id in todos) { tasksCopy.push({ ...todos[id], id: id }); } setTasks(tasksCopy); }); } else { setTasks([]); } }, [user]); const renderItem = ({ item }) => ( <TaskTwo item={item} /> ); return ( <View style={styles.container}> <FlatList data={tasks} initialNumToRender={5} windowSize={4} renderItem={renderItem} keyExtractor={item => item.id} /> </View> ); }
已尝试的解决方案
- 更新1:将优先级更新函数移至Task组件内并移除useCallback,不再作为props传递,但点击时仍会重渲染
- 更新2:添加了
keyExtractor,并在memo化的Task组件中加入自定义相等函数,问题依旧存在
请问我哪里操作有误?如何阻止点击优先级复选框时整个FlatList重渲染?
内容的提问来源于stack exchange,提问作者Lloyd Rajoo
相关产品推荐
相关产品推荐

