diff --git a/CHANGELOG.md b/CHANGELOG.md index b3341aa8..031c07be 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -35,6 +35,7 @@ _Please add entries here for your pull requests that are not yet released._ #### Bug Fixes - Fix installation crash caused by absolute path for `source_entry_path` in default `config/webpacker.yml` coming from `shakapacker` version 6.x - #1216 +- Fix warning for loading `react-dom` in React 18 - #1269 ## 2.6.2 diff --git a/react_ujs/src/reactDomClient.js b/react_ujs/src/reactDomClient.js new file mode 100644 index 00000000..e1e883ae --- /dev/null +++ b/react_ujs/src/reactDomClient.js @@ -0,0 +1,24 @@ +import ReactDOM from "react-dom" + +const reactMajorVersion = ReactDOM.version?.split('.')[0] || 16 + +// TODO: once we require React 18, we can remove this and inline everything guarded by it. +const supportsRootApi = reactMajorVersion >= 18 + +let reactDomClient = ReactDOM + +if (supportsRootApi) { + // This will never throw an exception, but it's the way to tell Webpack the dependency is optional + // https://github.com/webpack/webpack/issues/339#issuecomment-47739112 + // Unfortunately, it only converts the error to a warning. + try { + // eslint-disable-next-line global-require,import/no-unresolved + reactDomClient = require('react-dom/client'); + } catch (e) { + // We should never get here, but if we do, we'll just use the default ReactDOM + // and live with the warning. + reactDomClient = ReactDOM; + } +} + +export default reactDomClient diff --git a/react_ujs/src/renderHelpers.js b/react_ujs/src/renderHelpers.js index ef0398db..36ab48d0 100644 --- a/react_ujs/src/renderHelpers.js +++ b/react_ujs/src/renderHelpers.js @@ -1,4 +1,4 @@ -import ReactDOM from "react-dom" +import ReactDOM from "./reactDomClient" export function supportsHydration() { return typeof ReactDOM.hydrate === "function" || typeof ReactDOM.hydrateRoot === "function"