【问题标题】:How can I set State based on other state in functional component?如何根据功能组件中的其他状态设置状态?
【发布时间】:2021-09-17 14:56:14
【问题描述】:

我构建了一个简单的待办事项应用程序,其中包含一系列待办事项:

const todos = [description: "walk dog", done: false]

我使用以下两种状态:

  const [alltodos, handleTodos] = useState(todos);
  const [opencount, countOpen] = useState(alltodos.length);

这是计算打开待办事项的函数:

  const countTodos = () => {
    const donetodos = alltodos.filter((item) => {
      return !item.done;
    });
    countOpen(donetodos.length);
  };

当我尝试添加新的待办事项时,我还想使用countTodos 函数更新opencount 状态。

  const submitTodo = (event) => {
    event.preventDefault();

    const data = {
      description: todo,
      done: false,
    };

    handleTodos([...alltodos, data]);
    console.log(alltodos);
    countTodos();
  };

这不能按预期工作,当我运行console.log(alltodos) 时,它会显示一个空数组。该函数本身可以工作,但它似乎有一个“延迟”,我猜是基于 useState 钩子的异步性质。

我尝试像这样将countTodos 函数作为回调传递,因为我在基于类的组件中看到了类似的东西。

handleTodos([...alltodos, data], () => {
  countTodos();
});

我收到以下错误:

Warning: State updates from the useState() and useReducer() Hooks don't support the second callback argument. To execute a side effect after rendering, declare it in the component body with useEffect().

我该如何解决这个问题?我根据另一个状态更新状态的最佳方式是什么?

【问题讨论】:

  • 回调不适用于功能组件

标签: javascript reactjs react-hooks use-state


【解决方案1】:

我认为您应该使用Effect,(在日志消息中明确说明)。这是一个例子:

useEffect(()=>{
    const donetodos = alltodos.filter((item) => {
      return !item.done;
    });
    countOpen(donetodos.length);
   //countTodos();
},[alltodos]];

您可以参考文档:https://reactjs.org/docs/hooks-effect.html

这是一个例子:https://codesandbox.io/s/react-hooks-useeffect-forked-4sly8

【讨论】:

  • 太好了,这行得通。我被告知 useEffect 应该只用于 API 调用和其他副作用,感谢这个 sn-p!
  • 你可以通过在useEffect中直接调用你的函数countTodos来优化它。
  • @NidhiDadiya:你能告诉我怎么做吗? “alltodos”依赖项不会阻止 countTodos 执行吗?
  • useEffect(()=>{ countTodos() },[alltodos]];
猜你喜欢
  • 2018-08-23
  • 2021-01-12
  • 2021-10-31
  • 2021-04-17
  • 2020-05-07
  • 1970-01-01
  • 2020-10-15
  • 2022-10-06
  • 2021-12-13
相关资源
最近更新 更多