Skip to content

Commit bab3995

Browse files
committed
Improve react-dom handling
1 parent 285633f commit bab3995

File tree

2 files changed

+15
-13
lines changed

2 files changed

+15
-13
lines changed

node_package/src/ClientSideRenderer.ts

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,12 @@
11
/* eslint-disable max-classes-per-file */
22

3-
import * as ReactDOM from 'react-dom';
43
import type { ReactElement } from 'react';
54
import type { RailsContext, RegisteredComponent, RenderFunction, Root } from './types/index.ts';
65

76
import { getRailsContext, resetRailsContext } from './context.ts';
87
import createReactOutput from './createReactOutput.ts';
98
import { isServerRenderHash } from './isServerRenderResult.ts';
10-
import { supportsRootApi } from './reactApis.cts';
9+
import { supportsHydrate, supportsRootApi, unmountComponentAtNode } from './reactApis.cts';
1110
import reactHydrateOrRender from './reactHydrateOrRender.ts';
1211
import { debugTurbolinks } from './turbolinksUtils.ts';
1312
import * as StoreRegistry from './StoreRegistry.ts';
@@ -102,7 +101,7 @@ class ComponentRenderer {
102101
}
103102

104103
// Hydrate if available and was server rendered
105-
const shouldHydrate = (supportsRootApi || 'hydrate' in ReactDOM) && !!domNode.innerHTML;
104+
const shouldHydrate = supportsHydrate && !!domNode.innerHTML;
106105

107106
const reactElementOrRouterResult = createReactOutput({
108107
componentObj,
@@ -154,9 +153,8 @@ You should return a React.Component always for the client side entry point.`);
154153
}
155154

156155
try {
157-
const unmountComponentAtNode = 'unmountComponentAtNode';
158156
// eslint-disable-next-line @typescript-eslint/no-deprecated
159-
ReactDOM[unmountComponentAtNode](domNode);
157+
unmountComponentAtNode(domNode);
160158
} catch (e: unknown) {
161159
const error = e instanceof Error ? e : new Error('Unknown error');
162160
console.info(

node_package/src/reactApis.cts

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ const reactMajorVersion = Number(ReactDOM.version?.split('.')[0]) || 16;
88
// TODO: once we require React 18, we can remove this and inline everything guarded by it.
99
export const supportsRootApi = reactMajorVersion >= 18;
1010

11+
export const supportsHydrate = supportsRootApi || 'hydrate' in ReactDOM;
12+
1113
// TODO: once React dependency is updated to >= 18, we can remove this and just
1214
// import ReactDOM from 'react-dom/client';
1315
let reactDomClient: typeof import('react-dom/client');
@@ -24,7 +26,7 @@ if (supportsRootApi) {
2426
}
2527
}
2628

27-
export const ReactDOMServer = (() => {
29+
export const ReactDOMServer = /* #__PURE */ (() => {
2830
try {
2931
// in react-dom v18+
3032
return require('react-dom/server') as typeof import('react-dom/server');
@@ -41,15 +43,12 @@ export const ReactDOMServer = (() => {
4143

4244
type HydrateOrRenderType = (domNode: Element, reactElement: ReactElement) => RenderReturnType;
4345

44-
/* eslint-disable @typescript-eslint/no-deprecated,@typescript-eslint/no-non-null-assertion --
46+
/* eslint-disable @typescript-eslint/no-deprecated,@typescript-eslint/no-non-null-assertion,react/no-deprecated --
4547
* while we need to support React 16
4648
*/
47-
const hydrateProp = 'hydrate';
48-
const renderProp = 'render';
49-
5049
export const reactHydrate: HydrateOrRenderType = supportsRootApi
5150
? reactDomClient!.hydrateRoot
52-
: (domNode, reactElement) => ReactDOM[hydrateProp](reactElement, domNode);
51+
: (domNode, reactElement) => ReactDOM.hydrate(reactElement, domNode);
5352

5453
export function reactRender(domNode: Element, reactElement: ReactElement): RenderReturnType {
5554
if (supportsRootApi) {
@@ -58,6 +57,11 @@ export function reactRender(domNode: Element, reactElement: ReactElement): Rende
5857
return root;
5958
}
6059

61-
return ReactDOM[renderProp](reactElement, domNode);
60+
// eslint-disable-next-line react/no-render-return-value
61+
return ReactDOM.render(reactElement, domNode);
6262
}
63-
/* eslint-enable @typescript-eslint/no-deprecated,@typescript-eslint/no-non-null-assertion */
63+
64+
export const unmountComponentAtNode: typeof import('react-dom').unmountComponentAtNode = supportsRootApi
65+
? // not used if we use root API
66+
() => false
67+
: ReactDOM.unmountComponentAtNode;

0 commit comments

Comments
 (0)