useState批处理的坑

2021-11-19  本文已影响0人  joyer_li

在学习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函数被批处理了。<br />

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

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函数不批处理了!<br />

查阅资料后发现,这是react hooks机制的一个缺陷,会计划在react 18中修复,说明文档在这:<br />https://github.com/reactwg/react-18/discussions/21<br />
<br />根据说明文档所说,不仅仅setTimeout批处理会失效,像Promise.then函数中也会失效。

上一篇下一篇

猜你喜欢

热点阅读