react18:React event hander\Promise\setTimeout\native event handler (or any other event are batched.--form react) // Before React 18 only React events were batched functionhandleClick() { setCount(c => c + 1); setFlag(f => !f); // React will only re-render once at the end (that's batching!) } setTimeout(() => { setCount(c => c + 1); setFlag(f => !f); // React will render twice, once for each state update (no batching) }, 1000); // ------------------------------- // After React 18 updates inside of timeouts, promises, // native event handlers or any other event are batched. functionhandleClick() { setCount(c => c + 1); setFlag(f => !f); // React will only re-render once at the end (that's batching!) } setTimeout(() => { setCount(c => c + 1); setFlag(f => !f); // React will only re-render once at the end (that's batching!) }, 1000);
备注:automatic batching 默认开启,但是可以使用 flushsync
1 2 3 4 5 6 7 8 9 10 11
import { flushSync } from"react-dom" functionhandleClick() { flushSync(() => { setCounter((c) => c + 1) }) // React has updated the DOM by now flushSync(() => { setFlag((f) => !f) }) // React has updated the DOM by now }
New apis for Library
useSyncExternalStore …
useInsertionEffect Concurrent mode
startTransition Concurrent mode
useDeferredValue …
useId useId is a hook for generating unique IDs that are stable across the server and client, while avoiding hydration mismatches
const id = useId() // -------- functionCheckbox() { const id = useId() return ( <> <labelhtmlFor={id}>Do you like React?</label> <inputid={id}type="checkbox"name="react" /> </> ) } // -----For multiple IDs in same component, append a suffix using the same id functionNameFields() { const id = useId() return ( <div> <labelhtmlFor={id + "-firstName"}>First Name</label> <div> <inputid={id + "-firstName"} type="text" /> </div> <labelhtmlFor={id + "-lastName"}>Last Name</label> <div> <inputid={id + "-lastName"} type="text" /> </div> </div> ) }
Concurrent mode
不属于新功能,是一种新的底层机制,成为众多新功能的基础。 Before:线型渲染,一个接着一个被触发,只要触发就无法终止。 After:本质上的变化,并发渲染,所有渲染都是可中断、继续、终止 可以在后台进行 可以有优先级(开发者可以决定渲染顺序) Trasition(新功能) 控制渲染优先级(分为高低两种优先级),useTransition\starttransition 默认都是高优先级(正常的 state 更新) 非 hooks 场景下你用 starttransition,使用该 API 进行包裹 Updates wrapped in startTransition are handled as non-urgent and will be interrupted if more urgent updates like clicks or key presses come in. If a transition gets interrupted by the user (for example, by typing multiple characters in a row), React will throw out the stale rendering work that wasn’t finished and render only the latest update.
// urgent: show what was type setInputValue(input) // Mark any state updates inside as transition. startTransitiono(() => { // Transition: Show the results setSearchQuery(input) }) // hooks
useTransition: a hook to start transitions, including a value to track the pending state. startTransition: a method to start transitions when the hook cannot be used.
React mounts the component. _ Layout effects are created. _ Effect effects are created. // After:
React mounts the component.
Layout effects are created.
Effect effects are created.
React simulates unmounting the component.
Layout effects are destroyed.
Effects are destroyed.
React simulates mounting the component with the previous state. _ Layout effect setup code runs _ Effect setup code runs configuring you Testing Environment before running test: // In your test setup file globalThis.IS_REACT_ACT_ENVIRONMENT = true; Deprecations react-dom: ReactDOM.render has been deprecated. Using it will warn and run your app in React 17 mode. react-dom: ReactDOM.hydrate has been deprecated. Using it will warn and run your app in React 17 mode. react-dom: ReactDOM.unmountComponentAtNode has been deprecated. react-dom: ReactDOM.renderSubtreeIntoContainer has been deprecated. react-dom/server: ReactDOMServer.renderToNodeStream has been deprecated.
About IE
dropping support for internet explorer, if you need to support Internet Explorer we recommend you stay with react 17;