在学习react的时,关于状态的生效时机,官方说明多个状态在同时执行的时候会被合并(批处理)。在学习hooks时,跟状态相关的useHooks也以为是同样的批处理。如下面代码:

import React, { useState, useEffect } from 'react';
import ReactDOM from 'react-dom';

const Demo = () => {
  const [a, setA] = useState('');
  const [b, setB] = useState('');

  useEffect(() => {
    console.log('触发更新拉');
  }, [a, b]);

  return (<span onClick={() => {
    setA(String(Math.random()));
    setB(String(Math.random()));
  }}>测试</span>);
};

ReactDOM.render(
  <Demo />,
  document.getElementById('container'),
);

再点击时会发现只触发一次,状态的set函数被批处理了。

但将上面的代码改动一下:

import React, { useState, useEffect } from 'react';
import ReactDOM from 'react-dom';

const Demo = () => {
  const [a, setA] = useState('');
  const [b, setB] = useState('');

  useEffect(() => {
    console.log('触发更新拉');
  }, [a, b]);

  return (<span onClick={() => {
    setTimeout(() => {
      setA(String(Math.random()));
      setB(String(Math.random()));
    }, 300);
  }}>测试</span>);
};

ReactDOM.render(
  <Demo />,
  document.getElementById('container'),
);

此时点击后,会发现触发了两次更细,状态的set函数不批处理了!

查阅资料后发现,这是react hooks机制的一个缺陷,会计划在react 18中修复,说明文档在这:
https://github.com/reactwg/react-18/discussions/21


根据说明文档所说,不仅仅setTimeout批处理会失效,像Promise.then函数中也会失效。


joyerli
158 声望5 粉丝

前端搬砖一枚,会分享一些对技术的个人理解和思考,还会分享一些自己解决实际碰到的业务需而设计的奇葩技术方案。