Next.js中数据新增、删除、编辑时如何触发数据重新获取?
解决方案
你当前代码失效的核心原因是:仅在新增逻辑中修改了added这个useEffect依赖值,编辑、删除逻辑中没有同步更新该值,所以对应操作后不会触发重新拉取。如果要沿用这个方案,需要在所有修改数据的操作完成后都更新added(比如setAdded(prev => prev + 1)),但这种手动维护触发态的方式在多组件场景下需要逐层透传状态或更新方法,维护成本很高。
下面提供两种更合理的实现方案,都不需要手动维护state触发请求:
方案1:使用Firestore实时监听(最适配你当前的技术栈)
你当前用的是一次性拉取数据的getDocs方法,换成Firestore自带的onSnapshot实时监听方法后,不需要手动触发任何请求,只要数据库中todos集合的数据发生新增、编辑、删除,前端会自动收到更新通知并同步最新数据。多组件场景下可以直接抽成自定义Hook复用,不需要传递任何状态。
// 抽成可复用的自定义Hook const useTodos = () => { const [todos, setTodos] = React.useState([]); const [loading, setLoading] = React.useState(true); React.useEffect(() => { const todosCol = collection(db, "todos"); // 开启实时监听,数据变更自动触发回调 const unsubscribe = onSnapshot(todosCol, (snapshot) => { const todoList = snapshot.docs.map(doc => ({ id: doc.id, // 建议带上文档id,后续编辑、删除操作都需要用到 ...doc.data() })); setTodos(todoList); setLoading(false); }); // 组件卸载时取消监听,避免内存泄漏 return () => unsubscribe(); }, []); return { todos, loading }; };
使用时只需要在任意需要用到todos数据的组件引入该Hook即可,所有组件会自动同步最新数据。
方案2:使用数据请求库统一管理(适用所有数据请求场景)
如果不需要实时推送,只需要手动操作完成后触发刷新,可以用Next.js生态常用的SWR或者TanStack Query,这类库会全局缓存请求结果,提供统一的刷新方法,不需要透传state,任意组件都可以触发全局数据更新。
以SWR为例:
首先抽离公共的请求方法:
const fetchTodos = async () => { const todosCol = collection(db, "todos"); const todoSnapshot = await getDocs(todosCol); return todoSnapshot.docs.map(doc => ({ id: doc.id, ...doc.data() })); };
在组件中使用:
import useSWR from 'swr'; const TodoList = () => { // 第一个参数为全局唯一的缓存key,所有使用该key的组件会共享同一份数据 const { data: todos, mutate } = useSWR('todos', fetchTodos); // 删除操作示例 const handleDelete = async (todoId) => { await deleteDoc(doc(db, "todos", todoId)); // 调用mutate即可触发所有使用了`todos`这个key的组件重新拉取数据 mutate(); }; // 编辑、新增操作完成后同样调用mutate即可触发刷新 const handleEdit = async (todoId, newData) => { await updateDoc(doc(db, "todos", todoId), newData); mutate(); }; };
如果不想引入第三方依赖,也可以通过React Context封装刷新方法来实现跨组件触发,但维护成本远高于以上两种方案,更推荐优先选用前两种实现。
内容的提问来源于stack exchange,提问作者Arefin Anwar
相关产品推荐
相关产品推荐

