Skip to content

Commit 8cd044f

Browse files
refactoring
1 parent fc7e293 commit 8cd044f

File tree

4 files changed

+26
-13
lines changed

4 files changed

+26
-13
lines changed

lib/react_on_rails/helper.rb

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -530,8 +530,13 @@ def build_react_component_result_for_server_rendered_hash(
530530
end
531531

532532
def compose_react_component_html_with_spec_and_console(component_specification_tag, rendered_output, console_script, dom_id = nil)
533-
add_component_to_pending_hydration_code = "window.#{ADD_COMPONENT_TO_PENDING_HYDRATION_FUNCTION}('#{dom_id}');"
534-
hydrate_script = dom_id.present? ? content_tag(:script, add_component_to_pending_hydration_code.html_safe) : ""
533+
hydrate_script = if dom_id.present?
534+
add_component_to_pending_hydration_code = "window.#{ADD_COMPONENT_TO_PENDING_HYDRATION_FUNCTION}('#{dom_id}');"
535+
content_tag(:script, add_component_to_pending_hydration_code.html_safe)
536+
else
537+
""
538+
end
539+
535540
# IMPORTANT: Ensure that we mark string as html_safe to avoid escaping.
536541
html_content = <<~HTML
537542
#{rendered_output}

node_package/src/ComponentRegistry.ts

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,14 @@
11
import React from 'react';
2-
import type { RegisteredComponent, ReactComponentOrRenderFunction, RenderFunction, ReactComponent } from './types/index';
2+
import {
3+
type RegisteredComponent,
4+
type ReactComponentOrRenderFunction,
5+
type RenderFunction,
6+
type ComponentRegistrationCallback,
7+
} from './types';
38
import isRenderFunction from './isRenderFunction';
49

510
const registeredComponents = new Map<string, RegisteredComponent>();
6-
const registrationCallbacks = new Map<string, Array<(component: RegisteredComponent) => void>>();
11+
const registrationCallbacks = new Map<string, Array<ComponentRegistrationCallback>>();
712

813
export default {
914
/**
@@ -12,8 +17,8 @@ export default {
1217
* @param callback Function called with the component details when registered
1318
*/
1419
onComponentRegistered(
15-
componentName: string,
16-
callback: (component: RegisteredComponent) => void
20+
componentName: string,
21+
callback: (component: RegisteredComponent) => void,
1722
): void {
1823
// If component is already registered, schedule callback
1924
const existingComponent = registeredComponents.get(componentName);
@@ -63,7 +68,7 @@ export default {
6368

6469
registerServerComponent(...componentNames: string[]): void {
6570
// eslint-disable-next-line global-require, @typescript-eslint/no-var-requires
66-
const RSCClientRoot = require('./RSCClientRoot').default;
71+
const RSCClientRoot = (require('./RSCClientRoot') as typeof import('./RSCClientRoot')).default;
6772

6873
const componentsWrappedInRSCClientRoot = componentNames.reduce(
6974
(acc, name) => ({ ...acc, [name]: () => React.createElement(RSCClientRoot, { componentName: name }) }),

node_package/src/RSCClientRoot.ts

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,18 +2,16 @@ import * as React from 'react';
22
import RSDWClient from 'react-server-dom-webpack/client';
33

44
if (!('use' in React)) {
5-
throw new Error('React.use is not defined. Please ensure you are using React 18.3.0-canary-670811593-20240322 or later to use server components.');
5+
throw new Error('React.use is not defined. Please ensure you are using React 18 with experimental features enabled or React 19+ to use server components.');
66
}
77

8-
// It's not the exact type, but it's close enough for now
9-
type Use = <T>(promise: Promise<T>) => T;
10-
const { use } = React as { use: Use };
8+
const { use } = React;
119

12-
const renderCache: Record<string, Promise<unknown>> = {};
10+
const renderCache: Record<string, Promise<React.ReactNode>> = {};
1311

1412
const fetchRSC = ({ componentName }: { componentName: string }) => {
1513
if (!renderCache[componentName]) {
16-
renderCache[componentName] = RSDWClient.createFromFetch(fetch(`/rsc/${componentName}`));
14+
renderCache[componentName] = RSDWClient.createFromFetch(fetch(`/rsc/${componentName}`)) as Promise<React.ReactNode>;
1715
}
1816
return renderCache[componentName];
1917
}

node_package/src/types/index.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
// eslint-disable-next-line spaced-comment
2+
/// <reference types="react/experimental" />
3+
14
import type { ReactElement, ReactNode, Component, ComponentType } from 'react';
25
import type { Readable, PassThrough } from 'stream';
36

@@ -104,6 +107,8 @@ export interface RegisteredComponent {
104107
isRenderer: boolean;
105108
}
106109

110+
export type ComponentRegistrationCallback = (component: RegisteredComponent) => void;
111+
107112
interface Params {
108113
props?: Record<string, unknown>;
109114
railsContext?: RailsContext;

0 commit comments

Comments
 (0)