React函数组件中如何基于已有state更新另一个state?
问题根源
React 中 useState 的状态更新是批量异步的,调用状态更新函数后,当前作用域内的状态还是更新前的旧值,因此你在 handleTodos 后立刻读取 alltodos 拿到的还是旧数据;同时 useState 本身不支持类组件 setState 的第二个回调参数,所以你的回调写法会触发报错。
最优解决方案:优先使用派生状态
opencount 完全可以通过 alltodos 直接计算得到,不需要单独维护为独立 state,从根源上避免两个状态同步的问题:
// 需要用到opencount的地方直接计算,不需要单独声明state const opencount = alltodos.filter(item => !item.done).length; // 如果担心计算性能,可以用useMemo缓存计算结果 import { useMemo } from 'react'; const opencount = useMemo(() => { return alltodos.filter(item => !item.done).length; }, [alltodos]);
这种方案省去了手动同步两个状态的代码,也不会出现更新延迟问题,是官方推荐的最佳实践。
备选方案:用useEffect监听依赖状态更新
如果你确实需要保留opencount作为独立state,可以用useEffect监听alltodos的变化,自动触发opencount的更新:
import { useEffect } from 'react'; // 放在组件顶层即可,所有alltodos的修改都会自动触发更新 useEffect(() => { const undoneTodos = alltodos.filter(item => !item.done); countOpen(undoneTodos.length); }, [alltodos]);
此时你不需要在submitTodo里手动调用countTodos,只要alltodos发生变化,opencount会自动同步更新。
补充说明
你代码里的初始待办数组写法有误,数组内的对象缺少大括号,修正后为:
const todos = [{description: "walk dog", done: false}]
你在submitTodo里打印alltodos拿到旧值是正常的闭包特性,要查看最新的状态可以在React DevTools里查看组件状态,或者在useEffect里监听alltodos打印。
内容的提问来源于stack exchange,提问作者Data Mastery
相关产品推荐
相关产品推荐

