收集16.8 到 18 react 常用工作中更新了一些什么?

534 阅读4分钟

好久没看react更新了什么了,今天来看看 ?

react 17
  • react 17 为新的 JSX 转换添加react/jsx-runtime和。在react/jsx-dev-runtime React 16.14.0,React 15.7.0 和 0.14.0 版本做了兼容 (如果打包兼容的需要配置, @babel/preset-react 需要配置"runtime": "classic" 默认 classic react17的版本设置automatic 需要自己手动判断, 后期babel 8 后期默认automatic

  • react 17 比16 多了useEffect函数清除异步执行! 怎么理解,就是17以前的版本执是useEffect 的清理函数会在 commit 阶段执行 。这意味着当组件卸载时,React 先会执行清理函数,然后才会更新屏幕。,17现在变成异步,useEffect 的清理函数会延迟到 commit 阶段完成之后才会执行。换句话说, useEffect 清理函数被更改为异步执行,比如组卸载时,清理函数会在屏幕更新后执行,提升性能。

react-dom 17
  • 事件委托的跟新

image.png

不再是绑定 document 而是绑定根目录

  • 删除事件池 e.persist()以前异步访问需要设置这个,现在不需要了

  • 使用浏览器focusinfocusoutforonFocusonBlur ,支持冒泡,focusblur不能冒泡

react 18
  • usestate react 同时设置2个setstate 在同步方法执行一次 和在异步方法执行2次,18都是 render都是执行一次,修复了以前问题,还有设置state值时,以前在异步方法,可以拿到最新的值,react18 不能拿到最新的值,除非用
handleClick = () => {
  setTimeout(() => {
    this.setState(({ count }) => ({ count: count + 1 }));

    // { count: 0, flag: false }
    console.log(this.state);

    this.setState(({ flag }) => ({ flag: !flag }));
  });
};
handleClick = () => {
  setTimeout(() => {
    ReactDOM.flushSync(() => {
      this.setState(({ count }) => ({ count: count + 1 }));
    });

    // { count: 1, flag: false }
    console.log(this.state);

    this.setState(({ flag }) => ({ flag: !flag }));
  });
};

下面react 更新了一下新的hook api

  1. useId 用于在客户端和服务器上生成唯一 ID (测试每次render都会变)
  2. useTransition,startTransition 快速渲染的时候会导致卡顿,这个可以延迟时间,让紧急的线执行,流程程度,startTransition中的延迟更新,不会触发Suspens组件的fallback,便于用户在更新期间的交互(测试如果一个合成事件里面有2个usestate设置,在startTransition里面的会等待第一个渲染完成再去渲染startTransition里面的)
  3. useDeferredValue 参考文档 这网上说有2个参数,但是我在react ts类型定义上发现只有一个源码也只有一个参数
//源码
function useDeferredValue(value) {
  var dispatcher = resolveDispatcher();
  return dispatcher.useDeferredValue(value);
}
//ts类型
export function useDeferredValue<T>(value: T): T;

useTranstion和useDeferredValue异同:

  • 相同点: useDeferredValue本质上和内部实现与useTransition一样都是标记成了过渡更新任务。
  • 不同点:seDeferredValue本质上在useEffect内部执行,而useEffect内部逻辑是异步执行的,所以它一定程度上更滞后于useTransition, startTransition的回调函数是同步执行的。 在startTransition之中任何更新,都会标记上transition,React将在更新的时候,判断这个标记来决定是否完成此次更新。所以Transition可以理解成比setTimeout更早的更新。 但是同时要保证ui的正常响应,在性能好的设备上,transition两次更新的延迟会很小,但是在慢的设备上,延时会很大,但是不会影响UI的响应。
  1. useSyncExternalStore 参考文档 这个一般在库里面使用,目前react-redux 7出现问题, 8就可以了

5.useInsertionEffect是一个新的钩子,它允许 CSS-in-JS 库解决在渲染中注入样式的性能问题。除非您已经构建了 CSS-in-JS 库,否则我们不希望您使用它。这个钩子将在 DOM 发生变异之后运行,但在布局效果读取新布局之前。这解决了在 React 17 及更低版本中已经存在的问题,但在 React 18 中更为重要,因为 React 在并发渲染期间屈服于浏览器,使其有机会重新计算布局。

react-dom 18
  • react-dom:ReactDOM.render已弃用。使用它会警告并在 React 17 模式下运行您的应用程序。 替换createRoot
  • react-dom:ReactDOM.hydrate已弃用。使用它会警告并在 React 17 模式下运行您的应用程序。 替换 hydrateRoot
  • react-dom:ReactDOM.unmountComponentAtNode已弃用。 unmountComponentAtNode 替换 root.unmount
  • react-dom:ReactDOM.renderSubtreeIntoContainer已弃用。 (这个没用过,目前不知道干嘛)
  • react-dom/server:ReactDOMServer.renderToNodeStream已弃用(这个没用过,目前不知道干嘛)。

以上是我总结,欢迎有人一起补充!