如何在React Hooks中使用`setState`回调函数

392

React hooks引入useState来设置组件状态。但是我该如何使用hooks来替换下面的回调函数:

setState(
  { name: "Michael" },
  () => console.log(this.state)
);

状态更新后我想做一些事情。

我知道我可以使用 useEffect 来完成额外的操作,但是我需要检查前一个状态值,这需要写一些代码。我正在寻找一个简单的解决方案,可以与 useState 钩子一起使用。


2
在类组件中,我使用了async和await来实现像你在setState中添加回调函数一样的结果。不幸的是,在hook中它并不起作用。即使我添加了async和await,React也不会等待状态更新。也许useEffect是唯一的解决方式。 - MING WU
有一种简单的方法可以在不使用 useEffect 的情况下完成这个。https://dev59.com/C1QJ5IYBdhLWcg3wVEZ0#70405577 - Tunn
23个回答

-2

我认为你需要使用 useStateuseCallback:

示例代码

import React, { useCallback, useState } from 'react';

const Test = () => {
  const [name, setName] = useState("");
  const testCallback = useCallback(() => console.log(name), [name]);

  return (
    <button onClick={() => {
      setName("Michael")
      testCallback();
    }}>Name</button>
  )
};

export default Test;

-3
这样怎么样:
const [Name, setName] = useState("");
...
onClick={()=>{
setName("Michael")
setName(prevName=>{...}) //prevName is Michael?
}}


prevName 不会是 "Michael",因为 useState 和类组件中的 setState 一样都是异步的。你不能在一行代码中更新状态并假设它已经在下一行发生了改变。你很可能会使用未更改的状态。 - Zsolt Meszaros
好的,谢谢。我刚刚测试了这段代码,你是正确的。 - james h
很奇怪,prevName是Michael,但如果在回调函数中调用另一个使用名称的函数,它仍然没有更新。 - james h

-9

UseEffect是主要的解决方案。但正如Darryl所提到的,使用useEffect并将状态作为第二个参数传递有一个缺陷,即组件将在初始化过程中运行。如果您只想使用更新后的状态值运行回调函数,可以设置一个本地常量,并在setState和回调中使用它。

const [counter, setCounter] = useState(0);

const doSomething = () => {
  const updatedNumber = 123;
  setCounter(updatedNumber);

  // now you can "do something" with updatedNumber and don't have to worry about the async nature of setState!
  console.log(updatedNumber);
}

8
setCounter是异步的,你不确定console.log会在setCounter之后还是之前被调用。 - Mohit Singh
他想要将其拆分为另一个变量,以便在等待setState回调之前可以进行下一步操作。 - famfamfam

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接