2022-05-21 React18 异步渲染

2022-05-21  本文已影响0人  FConfidence
import React, { useCallback, useState } from 'react';
import SendButton from './SendButton';

export default function AsyncHook() {
  const [a, setA] = useState(0);
  const async = () => {
    setTimeout(() => {
      setA((c) => c + 1);
      window.console.log(a);
      setA((c) => c + 1);
      window.console.log(a);
      setA((c) => c + 1);
      window.console.log(a);
      // react17: 结果加3, renderTime 3次
    }, 0);
  };

  const async2 = () => {
    setTimeout(() => {
      setA(a + 1);
      window.console.log(a);
      setA(a + 1);
      window.console.log(a);
      setA(a + 1);
      window.console.log(a);
    }, 0);

    // react17: 结果+1, renderTime 调用2次
  };

  const sync = () => {
    setA((c) => c + 1);
    window.console.log(a);
    setA((c) => c + 1);
    window.console.log(a);
    setA((c) => c + 1);
    window.console.log(a);
    // react17: 结果+3, renderTime 调用1次
  };

  const sync2 = () => {
    setA(a + 1);
    window.console.log(a);
    setA(a + 1);
    window.console.log(a);
    setA(a + 1);
    window.console.log(a);
    // react17: 结果+1, render time调用一次
    // React18: 结果+1, render time调用一次 (上述几个demo表现与这个一致)
  };

  window.console.log('render times', a);

  const [text, setText] = useState('');

  const onClick = useCallback(() => {
    window.console.log('send: ', text);
  }, []);

  const onTextChange = (e: React.ChangeEvent<HTMLInputElement>) => {
    setText(e.target.value);
  };

  return (
    <div>
      <div>{a}</div>
      <button onClick={async} className="bg-teal-300">
        async
      </button>
      <button onClick={async2} className="bg-teal-300">
        async2
      </button>
      <button onClick={sync}>sync</button>
      <button onClick={sync2}>sync2</button>
      <hr />
      <input type="text" onChange={onTextChange} />
      <SendButton onSendMessage={onClick} />
    </div>
  );
}
/** 在React17中结果是一致的
 * 异步async render times会调用三次 结果+3
 * 异步async2 render times会调用2次, 结果加1

 * 同步: render times只调用一次, 结果+3
 * 同步: render times只调用一次, sync2 结果+1
 *
 * 结果都是增加三次
 *
 * react18中,
 * 异步 render times会调用一次
 * 同步: render times只调用一次
 * 行为保持了一致
 */
上一篇 下一篇

猜你喜欢

热点阅读