如何在MERN栈Todo应用中统计已完成任务数量
解决MERN Todo应用中已完成任务数统计问题
前端快速修复方案
首先你代码里存在一个关键问题:setTodos是异步操作,在then回调里直接用todos.length获取的是更新前的旧值,而且useEffect的依赖数组设为[todos]会导致无限请求循环。修改后可以直接从接口返回的res.data中统计数据:
const [todos, setTodos] = useState([]); const [todo, setTodo] = useState(""); const [amountDone, setAmountDone] = useState(0); const [amount, setAmount] = useState(0); useEffect(() => { axios .get("http://localhost:3001/") .then((res) => { const fetchedTodos = res.data; setTodos(fetchedTodos); // 统计总任务数 setAmount(fetchedTodos.length); // 过滤出status为true的任务并统计数量 const completedCount = fetchedTodos.filter(todo => todo.status === true).length; setAmountDone(completedCount); }) .catch((err) => console.log(err)); }, []); // 依赖数组改为空,仅在组件挂载时请求一次
后端优化方案(推荐)
如果Todo数据量较大,前端过滤会影响性能,建议在后端直接用MongoDB的统计API计算数量,再返回给前端:
后端路由修改(Node.js + Mongoose)
// 假设你的Todo模型已经定义 router.get('/', async (req, res) => { try { // 获取所有Todo列表 const todos = await Todo.find(); // 用countDocuments高效统计已完成任务数 const doneCount = await Todo.countDocuments({ status: true }); // 返回包含统计数据的结果 res.json({ todos, totalCount: todos.length, doneCount }); } catch (err) { res.status(500).json({ message: err.message }); } });
前端对应修改
useEffect(() => { axios .get("http://localhost:3001/") .then((res) => { const { todos, totalCount, doneCount } = res.data; setTodos(todos); setAmount(totalCount); setAmountDone(doneCount); }) .catch((err) => console.log(err)); }, []);
实时更新统计数(可选)
当你切换任务完成状态时,无需重新请求所有数据,直接更新本地状态:
const handleStatus = (todo) => { axios.patch(`http://localhost:3001/${todo._id}`, { status: !todo.status }) .then(res => { // 更新本地Todo列表 setTodos(prev => prev.map(item => item._id === todo._id ? res.data : item)); // 更新已完成任务数 setAmountDone(prev => todo.status ? prev - 1 : prev + 1); }) .catch(err => console.log(err)); };
内容的提问来源于stack exchange,提问作者Murad PETROSYAN
相关产品推荐
相关产品推荐

