React:传入set函数中的函数参数会立刻执行吗?

React:传入set函数中的函数参数会立刻执行吗?
下面这段代码中console.log会打印[1, 2, 3, 4, 5, 3],也就说它打印的修改后的值。
但是在我理解中传入的这个函数参数应该不是立刻执行的吧。

  • 这里的console.log会不会异步打印呢?
  • 如果是的话,哪些情况下会异步打印,有没有官方说明?
function App() {
  const [nums, setNums] = useState({
    nums: [1, 2, 3, 4, 5],
  });
  function handleClick() {
    setNums((pre) => {
      pre.nums.push(3);
      return pre;
    });
    console.log('after setNums:', nums);
  }
  return <button onClick={handleClick}>1</button>;
}

stackblitiz

阅读 1.5k
avatarAI BotBETA

在React中,当你使用setFunction这样的setter函数来更新状态时,传入的函数参数并不会立即执行。它会被调度(schedule)以便在未来的某个时间点更新状态。这意味着,如果你在调用setFunction之后立即尝试读取新的状态,你可能会得到旧的值,因为新的状态更新可能还没有发生。

然而,在你的代码中,console.log并不是直接打印nums状态的值,而是打印一个字符串,这个字符串包含了nums状态的一个表示。在JavaScript中,对象和数组是通过引用传递的,所以当你在setNums的函数参数中修改pre.nums时,这个修改会影响到nums状态。因此,console.log打印的是修改后的nums状态的引用。

至于console.log是否异步打印,这取决于具体的JavaScript运行环境。在某些环境(如浏览器的控制台)中,console.log可能是异步的,这意味着它可能不会立即显示输出,而是在稍后的某个时间点显示。然而,这并不是由console.log函数本身决定的,而是由运行环境决定的。

总的来说,当你在setFunction中传入一个函数参数来更新状态时,这个函数参数并不会立即执行。而console.log的行为则取决于它所在的运行环境。在React中,如果你想在状态更新后执行某些操作,你应该使用useEffect钩子来监听状态的变化。

2 个回答

因为setNums状态更新是异步的,处理完打印出来是更新前的值,想看到更新后的用useEffect监听这个值的变化就行。

function App() {
  const [nums, setNums] = useState([1, 2, 3, 4, 5]);

  useEffect(() => {
    console.log('Nums updated:', nums);
  }, [nums]);

  function handleClick() {
    setNums(prevNums => {
      
      return [...prevNums, 3];
    });
  }

  return <button onClick={handleClick}>Add 3</button>;
}

你上面的代码相当于 class 中的 this.state.nums=xxx 这样赋值了,你可以在App内打印一下 console.log('nums:', nums); 可以看到根本没有重新打印

你把代码改成下面这样 , 就会是你期待的异步效果了
function App() {
  const [nums, setNums] = useState({
    nums: [1, 2, 3, 4, 5],
  });
  const handleClick = useCallback(() => {
    setNums((pre) => {
      const temp = JSON.parse(JSON.stringify(pre));
      temp.nums.push(3);
      return temp;
    });
    console.log('after setNums:', nums);
  }, [nums]);

  console.log('nums:', nums);

  return <button onClick={handleClick}>1</button>;
}

export default App;
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题
宣传栏