wave icon indicating copy to clipboard operation
wave copied to clipboard

Research what changes are needed in Wave to support React 18

Open nlopin opened this issue 2 years ago • 4 comments

React@18 has just come up. Our package.json implicitly allows us to use it with Wave. We need to verify it is the case and create a migration task in case an additional effort is needed.

nlopin avatar Apr 07 '22 09:04 nlopin

Linking upgrade guide: https://reactjs.org/blog/2022/03/08/react-18-upgrade-guide.html

GIST and main takeouts:

May be relevant

  • Legacy root API replaced with completely new root API with concurrent rendering features and ReactDOM.render is no longer supported in React 18. -> https://reactjs.org/blog/2022/03/08/react-18-upgrade-guide.html#updates-to-client-rendering-apis
  • useInsertionEffect is a new hook that allows CSS-in-JS libraries to address performance issues of injecting styles in render -> https://github.com/reactwg/react-18/discussions/110
  • Automatic Batching: React 18 adds out-of-the-box performance improvements by doing more batching by default. With usage of createRoot, all updates since React 19 will be automatically batched, it doesn't matter where they originate from. "This means that updates inside of timeouts, promises, native event handlers or any other event will batch the same way as updates inside of React events." We can benefit from this, we can opt-out from this (this is a breaking change) with flushSync. More about this: https://github.com/reactwg/react-18/discussions/21
  • StrictMode is now bit more stricter, and "not all our components may be resilient to the new checks it adds in development mode" -> https://reactjs.org/blog/2022/03/08/react-18-upgrade-guide.html#updates-to-strict-mode
  • components / apps using server-side rendering with hydration need to update hydrate method to hydrateRoot
  • React 18 also introduces new APIs for concurrent rendering such as startTransition, useDeferredValue and useId, more about these on CHANGELOG
  • needed updates to tests and test setup files, configure testing environment to support act() method -> https://github.com/reactwg/react-18/discussions/102
  • but good news: React Testing Library just released V13 that supports React 18: https://github.com/testing-library/react-testing-library/issues/509#issuecomment-917989936

Other

  • Revamp of react-dom/server: Old Node streaming API and renderToNodeStream are deprecated. New APIs that support streaming SSR with Suspense (renderToPipeableStream, renderToReadableStream)
  • useSyncExternalStore is a new hook that allows external stores to support concurrent reads by forcing updates to the store to be synchronous.
  • completely dropping support for Internet Explorer 🥳
  • Components can now render undefined

Deprecations

JanHamara avatar Apr 07 '22 15:04 JanHamara

useId is something we need to migrate to, because we're currently generating ids using an external library and it doesn't work well with SSR

nlopin avatar Apr 08 '22 06:04 nlopin

One more thing to do is to update components type declarations that use React.FC because in @types/react@18x FC can't have children by default:

interface FunctionComponent<P = {}> {
-  (props: PropsWithChildren<P>, context?: any): ReactElement<any, any> | null;
+  (props: P, context?: any): ReactElement<any, any> | null;
   propTypes?: WeakValidationMap<P> | undefined;
   contextTypes?: ValidationMap<any> | undefined;
   defaultProps?: Partial<P> | undefined;
   displayName?: string | undefined;
}

PropsWithChildren now isn't used anywhere, just exported. We have to replace React.FC<Props> with React.FC<PropsWithChildren<Props>>.

vitalybaev avatar May 06 '22 11:05 vitalybaev

I think for the current major we can just allow using Wave with react@18 without any changes (only in package.json)

For the next major we should start using the new React@18 concurrent engine in order to utilize new hooks. For example, we can remove nanoid because react@18 has useId hook with the same functionality

nlopin avatar Jun 03 '22 13:06 nlopin

Since this issue was meant to be a research to see if we can support or not React 18 and we already support it in Wave 2.0 I am closing it, any other enhancements related to React 18 can be in the form of new issues

martimalek avatar Feb 14 '24 12:02 martimalek