【React 】react 18

449 阅读2分钟

What is Concurrent React(并发渲染)

并发模式进行可中断渲染

查阅了一些资料

其目的为了提升帮助React应用保持响应,并优雅地适应用户的设备功能和网络速度

因为有了这个并发渲染,Suspense, transitions, and SSR都是充分并发渲染去构建的

可重用的状态

接下来的小版本可能会增加 Offscreen

New Feature: Automatic Batching

ReactDOM.flushSync()

github.com/reactwg/rea…

这看起来很像是一个使用者不需要太关心的feature,因为react 18自动处理了。在使用timeouts、promises、natives event handler或者其他events的更新将以与React事件中的更新相同的方式进行批处理,嗯嗯...就是为了减少渲染次数

懒得复制代码了,直接截图

函数式组件

image.png

最终只会渲染一次

Class组件

image.png

不想自动批处理

import { flushSync } from 'react-dom'; // Note: react-dom, not react

function handleClick() {
  flushSync(() => {
    setCounter(c => c + 1);
  });
  // React has updated the DOM by now
  flushSync(() => {
    setFlag(f => !f);
  });
  // React has updated the DOM by now
}

官方不推荐介么做啦

New Feature Transitions

New Features Suspense

github.com/reactwg/rea…

New Client and Server Rendering APIs

Client Rendering APIs

Before`React 18
Updates to Client Rendering APIsReactDOM.renderReactDOM.createRoot
UnmountunmountComponentAtNoderoot.unmount
移除了render的callback
Server-side renderinghydratehydrateRoot

changed ReactDOM.render to ReactDOM.createRoot


// Before
import { render } from 'react-dom';
const container = document.getElementById('app');
render(<App tab="home" />, container);

// After
import { createRoot } from 'react-dom/client';
const container = document.getElementById('app');
const root = createRoot(container);
root.render(<App tab="home" />);

changed unmountComponentAtNode to root.unmount

// Before
unmountComponentAtNode(container);

// After
root.unmount();

移除了render的callback

// Before
const container = document.getElementById('app');
ReactDOM.render(<App tab="home" />, container, () => {
  console.log('rendered');
});

// After
function AppWithCallbackAfterRender() {
  useEffect(() => {
    console.log('rendered');
  });

  return <App tab="home" />
}

const container = document.getElementById('app');
const root = ReactDOM.createRoot(container);
root.render(<AppWithCallbackAfterRender />);

移除的原因是因为

因为它在使用 Suspense 时通常没有预期的结果

尴尬这个Suspense只是听闻过,但是没有使用过

SSR hydrate 替换为 hydrateRoot

// Before
import { hydrate } from 'react-dom';
const container = document.getElementById('app');
hydrate(<App tab="home" />, container);

// After
import { hydrateRoot } from 'react-dom/client';
const container = document.getElementById('app');
const root = hydrateRoot(container, <App tab="home" />);
//  哈哈,这里可以用不createRoot

也没有用过

Server Rendering APIs

The following APIs will continue working, but with limited support for Suspense

These additional methods depend on a package (stream) that is only available on the server, and won’t work in the browser.

介绍新的API

renderToPipeableStream

renderToString>renderToPipeableStream

renderToReadableStream

New Strict Mode Behaviors

新的hooks

  • useTransition

  • startTransition

github.com/reactwg/rea…

github.com/reactwg/rea…

  • useDeferredValue

有点类似于防抖的功能

  • useInsertionEffect

  • useId

  • useSyncExternalStore

从另一个维度看这次更新

image.png

github.com/reactwg/rea…

discussions真是个好东西,可以及时看到更新的知识点