使用react-native-draggable-flatlist实现可拖拽待办列表时遭遇TypeError: undefined is not a function错误排查
Let's break down the possible issues with your code and fix them step by step:
1. Incorrect Import of DraggableFlatList
The most likely culprit here is a wrong import statement. react-native-draggable-flatlist uses a default export, not a named export. If you're importing it with curly braces, DraggableFlatList will be undefined, which directly causes the "undefined is not a function" error when you try to render it.
Check and fix your import:
// ❌ Wrong (named import won't work) import { DraggableFlatList } from 'react-native-draggable-flatlist'; // ✅ Correct (default import) import DraggableFlatList from 'react-native-draggable-flatlist';
2. You Never Call loadData()
Your loadData function is defined but never executed, so unfinishedTodos stays an empty array forever. While an empty array might not trigger this exact error, it's critical to fetch your data on component mount. Add a useEffect hook to call it:
First, import useEffect from React:
import { useState, useEffect } from 'react';
Then add the hook inside your component:
useEffect(() => { loadData(); }, []); // Empty dependency array ensures this runs once when the component mounts
3. Update loadData for Better Error Handling & Logic
Your loadData has a minor flaw: you set loading to true after the data is fetched, which is backwards. Also, use forEach instead of map when pushing to an array (map is meant to return a new array, not for side effects):
function loadData() { setLoading(true); // Set loading at the start of the request firestore() .collection('todos') .orderBy('priority', 'desc') .get() .then(snap => { let unfinished = []; snap.docs.forEach(each => { let eachdict = { id: each.id, taskName: each.get('taskName'), taskDesc: each.get('taskDesc'), priority: each.get('priority'), finished: each.get('finished'), time: each.get('time'), index: each.get('index'), timeType: each.get('timeType'), }; unfinished.push(eachdict); }); setUnfinishedTodos( unfinished.sort((a, b) => a.index - b.index) ); setLoading(false); }) .catch(error => { console.log(error.message); setLoading(false); // Don't forget to turn off loading on error }); }
4. Fix RenderItem to Enable Drag Functionality
While this isn't causing your current error, your renderItem doesn't use the drag function, so users won't be able to actually drag items. Wrap your text in an interactive component (like TouchableOpacity) and bind drag to onLongPress:
renderItem={({item, index, drag, isActive}) => { return ( <TouchableOpacity onLongPress={drag} style={{ padding: 16, backgroundColor: isActive ? '#f0f0f0' : 'white', borderBottomWidth: 1, borderBottomColor: '#eee' }} > <Text>{item.taskName}</Text> </TouchableOpacity> ) }}
5. Update State on Drag End
Right now you're just logging the reordered data, but you need to update your state to persist the new order:
onDragEnd={({data}) => setUnfinishedTodos(data)}
After applying these fixes, your error should be resolved, and your draggable todo list should work as expected.
内容的提问来源于stack exchange,提问作者Pro

