Next.js待办应用删除任务后如何实现列表自动刷新
问题根因
- 你封装的
useFetchTasksHook 已经实现了主动拉取最新任务列表的fetchTasks方法,但IndexPage组件解构Hook返回值时仅取出了tasks字段,没有用到刷新方法 - 删除按钮所在的
OperationButtons子组件没有接收列表刷新的回调,删除接口调用成功后无法触发列表状态更新
修复方案
两种实现思路选一个即可,不需要额外引入依赖。
方案1:删除成功后重新拉取接口(数据一致性更高)
适合多端同时操作任务的场景,能保证拿到的列表和服务端完全一致。
- 修改
IndexPage组件,从Hook中取出fetchTasks方法,作为回调传给操作按钮组件:
const IndexPage = () => { // 取出已封装的列表刷新方法 const { tasks, fetchTasks } = useFetchTasks(); return ( <> <Typography variant="h3" align="center" marginTop={3}> TODO LIST </Typography> {tasks && ( <Container maxWidth="sm"> <List sx={{ width: "100%" }}> {tasks.tasks.map((task) => ( <ListItem key={task.id} secondaryAction={ <OperationButtons taskId={task.id} onDeleteSuccess={fetchTasks} /> } > <ListItemAvatar> <Avatar> <FactCheckIcon /> </Avatar> </ListItemAvatar> <ListItemText primary={task.description} secondary={task.created_at} /> </ListItem> ))} </List> </Container> )} </> ); };
- 修改
OperationButtons组件,新增回调类型定义,删除接口请求成功后执行回调:
interface OperationButtonProps { taskId: number; onDeleteSuccess: () => void; } const OperationButtons: React.VFC<OperationButtonProps> = (props) => { const handleDelete = async () => { try { await deleteTask(props.taskId); // 删除成功后触发父组件传入的刷新逻辑 props.onDeleteSuccess(); } catch (e) { console.log(e); } }; return ( <Stack direction="row"> <IconButton aria-label="edit"> <EditIcon /> </IconButton> <IconButton edge="end" aria-label="delete" onClick={handleDelete}> <DeleteIcon /> </IconButton> </Stack> ); };
方案2:删除成功后直接更新本地状态(体验更流畅)
适合单用户使用的场景,省一次接口请求,操作后立刻看到反馈,没有loading等待。
先扩展useFetchTasks的能力,新增本地删除任务的方法:
// modules/hooks/useFetchTasks.ts import { useState, useEffect, useCallback } from "react"; import { getTasks, TasksResponse } from "../apiClient/tasks/getTasks"; export const useFetchTasks = () => { const [tasks, setTasks] = useState<TasksResponse | null>(null); const fetchTasks = useCallback(async () => { try { const { data } = await getTasks(); setTasks(data); } catch (e) { console.log(e); } }, []); // 新增本地删除方法,直接过滤state中的目标任务 const removeTaskLocally = useCallback((targetTaskId: number) => { setTasks(prev => { if (!prev) return prev; return { ...prev, tasks: prev.tasks.filter(task => task.id !== targetTaskId) } }) }, []) useEffect(() => { fetchTasks(); }, [fetchTasks]); return { tasks, fetchTasks, removeTaskLocally }; };
之后IndexPage里把removeTaskLocally作为回调传给OperationButtons即可,组件Props的改法和方案1一致,不需要再发GET请求。
内容的提问来源于stack exchange,提问作者ta539tg70
相关产品推荐
相关产品推荐

