From fa78795e206cd43e4dd42ef198f614232399908b Mon Sep 17 00:00:00 2001 From: Justin Gordon Date: Thu, 6 Nov 2025 22:58:50 -1000 Subject: [PATCH] [React 19] Update OSS package imports for consistency with Pro MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This PR updates the open-source package to use the same import pattern as the Pro package, ensuring consistency across the codebase. ## Changes Changed from namespace imports to named imports in 3 OSS files: **Before (inconsistent with Pro):** ```typescript import * as React from 'react'; React.createElement() React.isValidElement() ``` **After (consistent with Pro):** ```typescript import { createElement, isValidElement } from 'react'; createElement() isValidElement() ``` ### Files Updated 1. `packages/react-on-rails/src/createReactOutput.ts` - `React.createElement` → `createElement` - `React.isValidElement` → `isValidElement` - `React.ReactElement` type → `ReactElement` type 2. `packages/react-on-rails/src/handleError.ts` - `React.createElement` → `createElement` 3. `packages/react-on-rails/src/serverRenderReactComponent.ts` - `React.isValidElement` → `isValidElement` - Consolidated duplicate ReactElement import ## Why This Matters **Consistency:** Pro package (PR #1943) uses named imports. This brings OSS in line. **React 19 Best Practice:** Named imports are the recommended pattern for React 19: - Better tree-shaking - Clearer dependencies - More explicit code **No Breaking Changes:** Both patterns work with React 18 and 19. ## Testing ✅ Builds successfully ✅ All existing tests pass ✅ No API changes ✅ Runtime behavior unchanged ## Dependencies - Independent of PR #1942 and #1943 - Can merge in any order - Purely a code style/consistency improvement ## Impact - ✅ Improves codebase consistency - ✅ Follows React 19 best practices - ✅ No breaking changes - ✅ Works with React 18 and 19 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- packages/react-on-rails/src/createReactOutput.ts | 10 +++++----- packages/react-on-rails/src/handleError.ts | 4 ++-- .../react-on-rails/src/serverRenderReactComponent.ts | 5 ++--- 3 files changed, 9 insertions(+), 10 deletions(-) diff --git a/packages/react-on-rails/src/createReactOutput.ts b/packages/react-on-rails/src/createReactOutput.ts index a63f886498..93f51eb8a6 100644 --- a/packages/react-on-rails/src/createReactOutput.ts +++ b/packages/react-on-rails/src/createReactOutput.ts @@ -1,4 +1,4 @@ -import * as React from 'react'; +import { createElement, isValidElement, type ReactElement } from 'react'; import type { CreateParams, ReactComponent, RenderFunction, CreateReactOutputResult } from './types/index.ts'; import { isServerRenderHash, isPromise } from './isServerRenderResult.ts'; @@ -6,8 +6,8 @@ function createReactElementFromRenderFunctionResult( renderFunctionResult: ReactComponent, name: string, props: Record | undefined, -): React.ReactElement { - if (React.isValidElement(renderFunctionResult)) { +): ReactElement { + if (isValidElement(renderFunctionResult)) { // If already a ReactElement, then just return it. console.error( `Warning: ReactOnRails: Your registered render-function (ReactOnRails.register) for ${name} @@ -19,7 +19,7 @@ work if you return JSX. Update by wrapping the result JSX of ${name} in a fat ar } // If a component, then wrap in an element - return React.createElement(renderFunctionResult, props); + return createElement(renderFunctionResult, props); } /** @@ -88,5 +88,5 @@ export default function createReactOutput({ return createReactElementFromRenderFunctionResult(renderFunctionResult, name, props); } // else - return React.createElement(component as ReactComponent, props); + return createElement(component as ReactComponent, props); } diff --git a/packages/react-on-rails/src/handleError.ts b/packages/react-on-rails/src/handleError.ts index 3419f71586..c043dc0a2a 100644 --- a/packages/react-on-rails/src/handleError.ts +++ b/packages/react-on-rails/src/handleError.ts @@ -1,11 +1,11 @@ -import * as React from 'react'; +import { createElement } from 'react'; import { renderToString } from './ReactDOMServer.cts'; import type { ErrorOptions } from './types/index.ts'; import generateRenderingErrorMessage from './generateRenderingErrorMessage.ts'; const handleError = (options: ErrorOptions): string => { const msg = generateRenderingErrorMessage(options); - const reactElement = React.createElement('pre', null, msg); + const reactElement = createElement('pre', null, msg); return renderToString(reactElement); }; diff --git a/packages/react-on-rails/src/serverRenderReactComponent.ts b/packages/react-on-rails/src/serverRenderReactComponent.ts index f47c4e9542..328245518f 100644 --- a/packages/react-on-rails/src/serverRenderReactComponent.ts +++ b/packages/react-on-rails/src/serverRenderReactComponent.ts @@ -1,5 +1,4 @@ -import * as React from 'react'; -import type { ReactElement } from 'react'; +import { isValidElement, type ReactElement } from 'react'; // ComponentRegistry is accessed via globalThis.ReactOnRails.getComponent for cross-bundle compatibility import createReactOutput from './createReactOutput.ts'; @@ -69,7 +68,7 @@ function processPromise( return '{}'; } return result.then((promiseResult) => { - if (React.isValidElement(promiseResult)) { + if (isValidElement(promiseResult)) { return processReactElement(promiseResult); } return promiseResult;