Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: compatibility with react rc 2 #35108

Merged
merged 8 commits into from Mar 15, 2022
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
4 changes: 2 additions & 2 deletions packages/gatsby-link/package.json
Expand Up @@ -21,8 +21,8 @@
},
"peerDependencies": {
"@gatsbyjs/reach-router": "^1.3.5",
"react": "^16.9.0 || ^17.0.0",
"react-dom": "^16.9.0 || ^17.0.0"
"react": "^16.9.0 || ^17.0.0 || ^18.0.0",
"react-dom": "^16.9.0 || ^17.0.0 || ^18.0.0"
},
"homepage": "https://github.com/gatsbyjs/gatsby/tree/master/packages/gatsby-link#readme",
"keywords": [
Expand Down
4 changes: 2 additions & 2 deletions packages/gatsby-plugin-cxs/package.json
Expand Up @@ -28,8 +28,8 @@
"peerDependencies": {
"cxs": ">=5.0.0",
"gatsby": "^4.0.0-next",
"react": "^16.9.0 || ^17.0.0",
"react-dom": "^16.9.0 || ^17.0.0"
"react": "^16.9.0 || ^17.0.0 || ^18.0.0",
"react-dom": "^16.9.0 || ^17.0.0 || ^18.0.0"
},
"repository": {
"type": "git",
Expand Down
4 changes: 2 additions & 2 deletions packages/gatsby-plugin-feed/package.json
Expand Up @@ -33,8 +33,8 @@
"main": "index.js",
"peerDependencies": {
"gatsby": "^4.0.0-next",
"react": "^16.9.0 || ^17.0.0",
"react-dom": "^16.9.0 || ^17.0.0"
"react": "^16.9.0 || ^17.0.0 || ^18.0.0",
"react-dom": "^16.9.0 || ^17.0.0 || ^18.0.0"
},
"repository": {
"type": "git",
Expand Down
4 changes: 2 additions & 2 deletions packages/gatsby-plugin-fullstory/package.json
Expand Up @@ -34,8 +34,8 @@
},
"peerDependencies": {
"gatsby": "^4.0.0-next",
"react": "^16.9.0 || ^17.0.0",
"react-dom": "^16.9.0 || ^17.0.0"
"react": "^16.9.0 || ^17.0.0 || ^18.0.0",
"react-dom": "^16.9.0 || ^17.0.0 || ^18.0.0"
},
"engines": {
"node": ">=14.15.0"
Expand Down
4 changes: 2 additions & 2 deletions packages/gatsby-plugin-google-analytics/package.json
Expand Up @@ -28,8 +28,8 @@
"main": "index.js",
"peerDependencies": {
"gatsby": "^4.0.0-next",
"react": "^16.9.0 || ^17.0.0",
"react-dom": "^16.9.0 || ^17.0.0"
"react": "^16.9.0 || ^17.0.0 || ^18.0.0",
"react-dom": "^16.9.0 || ^17.0.0 || ^18.0.0"
},
"repository": {
"type": "git",
Expand Down
4 changes: 2 additions & 2 deletions packages/gatsby-plugin-google-gtag/package.json
Expand Up @@ -27,8 +27,8 @@
"main": "index.js",
"peerDependencies": {
"gatsby": "^4.0.0-next",
"react": "^16.9.0 || ^17.0.0",
"react-dom": "^16.9.0 || ^17.0.0"
"react": "^16.9.0 || ^17.0.0 || ^18.0.0",
"react-dom": "^16.9.0 || ^17.0.0 || ^18.0.0"
},
"repository": {
"type": "git",
Expand Down
4 changes: 2 additions & 2 deletions packages/gatsby-plugin-google-tagmanager/package.json
Expand Up @@ -28,8 +28,8 @@
"main": "index.js",
"peerDependencies": {
"gatsby": "^4.0.0-next",
"react": "^16.9.0 || ^17.0.0",
"react-dom": "^16.9.0 || ^17.0.0"
"react": "^16.9.0 || ^17.0.0 || ^18.0.0",
"react-dom": "^16.9.0 || ^17.0.0 || ^18.0.0"
},
"repository": {
"type": "git",
Expand Down
5 changes: 3 additions & 2 deletions packages/gatsby-plugin-image/package.json
Expand Up @@ -60,6 +60,7 @@
"microbundle": "^0.13.0",
"npm-run-all": "^4.1.5",
"postcss": "^8.2.9",
"semver": "^7.0.0",
"terser": "^5.3.8",
"typescript": "^4.5.5"
},
Expand All @@ -68,8 +69,8 @@
"gatsby": "^4.0.0-next",
"gatsby-plugin-sharp": "^4.0.0-next",
"gatsby-source-filesystem": "^4.0.0-next",
"react": "^16.9.0 || ^17.0.0",
"react-dom": "^16.9.0 || ^17.0.0"
"react": "^16.9.0 || ^17.0.0 || ^18.0.0",
"react-dom": "^16.9.0 || ^17.0.0 || ^18.0.0"
},
"dependencies": {
"@babel/code-frame": "^7.14.0",
Expand Down
@@ -1,3 +1,4 @@
/* global HAS_REACT_18 */
/* eslint-disable no-unused-expressions */
import React, {
Component,
Expand All @@ -22,7 +23,30 @@ import { Layout } from "../image-utils"
import { getSizer } from "./layout-wrapper"
import { propTypes } from "./gatsby-image.server"
import { Unobserver } from "./intersection-observer"
import { render } from "react-dom"

let reactRender
if (HAS_REACT_18) {
const reactDomClient = require(`react-dom/client`)
reactRender = (
Component: React.Component,
el: ReactDOM.Container,
root: any
): unknown => {
wardpeet marked this conversation as resolved.
Show resolved Hide resolved
if (!root) {
root = reactDomClient.createRoot(el)
}

// @ts-ignore - React 18 typings
root.render(Component)

return root
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe I'm missing some context here, but why is with React 18 the reactRender returning something, with older version it's void?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because Root doesn't exist in React < 18 and we need the root so we only call createRoot once.

}
} else {
const reactDomClient = require(`react-dom`)
reactRender = (Component: React.Component, el: ReactDOM.Container): void => {
reactDomClient.render(Component, el)
}
}

// eslint-disable-next-line @typescript-eslint/naming-convention
export interface GatsbyImageProps
Expand Down Expand Up @@ -69,6 +93,9 @@ class GatsbyImageHydrator extends Component<
lazyHydrator: () => void | null = null
ref = createRef<HTMLImageElement>()
unobserveRef: Unobserver
// TODO fix typing
// @ts-ignore - ignore
reactRootRef: MutableRefObject<unknown> = createRef<unknown>()

constructor(props) {
super(props)
Expand Down Expand Up @@ -108,7 +135,8 @@ class GatsbyImageHydrator extends Component<
},
this.root,
this.hydrated,
this.forceRender
this.forceRender,
this.reactRootRef
)
})
}
Expand Down Expand Up @@ -152,7 +180,11 @@ class GatsbyImageHydrator extends Component<

// // on unmount, make sure we cleanup
if (this.hydrated.current && this.lazyHydrator) {
render(null, this.root.current)
this.reactRootRef.current = reactRender(
null,
this.root.current,
this.reactRootRef.current
)
}
}

Expand Down
73 changes: 49 additions & 24 deletions packages/gatsby-plugin-image/src/components/lazy-hydrate.tsx
@@ -1,5 +1,5 @@
/* global HAS_REACT_18 */
import React, { MutableRefObject } from "react"
import ReactDOM from "react-dom"
import { GatsbyImageProps } from "./gatsby-image.browser"
import { LayoutWrapper } from "./layout-wrapper"
import { Placeholder } from "./placeholder"
Expand All @@ -14,6 +14,37 @@ type LazyHydrateProps = Omit<GatsbyImageProps, "as" | "style" | "className"> & {
ref: MutableRefObject<HTMLImageElement | undefined>
}

let reactRender
let reactHydrate
if (HAS_REACT_18) {
const reactDomClient = require(`react-dom/client`)
reactRender = (
Component: React.Component,
el: ReactDOM.Container,
root: any
): unknown => {
if (!root) {
root = reactDomClient.createRoot(el)
}

// TODO fix typing
// @ts-ignore - React 18 typings
root.render(Component)

return root
}
reactHydrate = (
Component: React.Component,
el: ReactDOM.Container
): unknown => reactDomClient.hydrateRoot(el, Component)
} else {
const reactDomClient = require(`react-dom`)
reactRender = (Component: React.Component, el: ReactDOM.Container): void => {
reactDomClient.render(Component, el)
}
reactHydrate = reactDomClient.hydrate
}

export function lazyHydrate(
{
image,
Expand All @@ -31,7 +62,8 @@ export function lazyHydrate(
}: LazyHydrateProps,
root: MutableRefObject<HTMLElement | undefined>,
hydrated: MutableRefObject<boolean>,
forceHydrate: MutableRefObject<boolean>
forceHydrate: MutableRefObject<boolean>,
reactRootRef: MutableRefObject<unknown>
): (() => void) | null {
const {
width,
Expand Down Expand Up @@ -87,34 +119,27 @@ export function lazyHydrate(

if (root.current) {
// Force render to mitigate "Expected server HTML to contain a matching" in develop
// @ts-ignore react 18 typings
if (ReactDOM.createRoot) {
if (!hydrated.current) {
// @ts-ignore react 18 typings
hydrated.current = ReactDOM.createRoot(root.current)
}

// @ts-ignore react 18 typings
hydrated.current.render(component)
if (hydrated.current || forceHydrate.current || HAS_REACT_18) {
// TODO fix typing
// @ts-ignore - React 18 typings
reactRootRef.current = reactRender(
component,
root.current,
reactRootRef.current
)
} else {
const doRender =
hydrated.current || forceHydrate.current
? ReactDOM.render
: ReactDOM.hydrate
doRender(component, root.current)
hydrated.current = true
reactHydrate(component, root.current)
}
hydrated.current = true
}

return (): void => {
if (root.current) {
// @ts-ignore react 18 typings
if (ReactDOM.createRoot) {
// @ts-ignore react 18 typings
hydrated.current.render(null)
} else {
ReactDOM.render(null as unknown as ReactElement, root.current)
}
reactRender(
null as unknown as ReactElement,
root.current,
reactRootRef.current
)
}
}
}
4 changes: 4 additions & 0 deletions packages/gatsby-plugin-image/src/gatsby-node.ts
Expand Up @@ -5,6 +5,7 @@ import {
ImageLayoutType,
ImagePlaceholderType,
} from "./resolver-utils"
import { major } from "semver"

export * from "./node-apis/preprocess-source"

Expand Down Expand Up @@ -51,6 +52,9 @@ export const onCreateWebpackConfig: GatsbyNode["onCreateWebpackConfig"] = ({
plugins.define({
// eslint-disable-next-line @typescript-eslint/naming-convention
GATSBY___IMAGE: true,
HAS_REACT_18: JSON.stringify(
major(require(`react-dom/package.json`).version) >= 18
),
}),
],
})
Expand Down
1 change: 1 addition & 0 deletions packages/gatsby-plugin-image/src/global.d.ts
Expand Up @@ -3,4 +3,5 @@ export {}
declare global {
declare var SERVER: boolean | undefined
declare var GATSBY___IMAGE: boolean | undefined
declare var HAS_REACT_18: boolean
}
4 changes: 2 additions & 2 deletions packages/gatsby-plugin-jss/package.json
Expand Up @@ -26,8 +26,8 @@
"main": "index.js",
"peerDependencies": {
"gatsby": "^4.0.0-next",
"react": "^16.9.0 || ^17.0.0",
"react-dom": "^16.9.0 || ^17.0.0"
"react": "^16.9.0 || ^17.0.0 || ^18.0.0",
"react-dom": "^16.9.0 || ^17.0.0 || ^18.0.0"
},
"repository": {
"type": "git",
Expand Down
4 changes: 2 additions & 2 deletions packages/gatsby-plugin-mdx/package.json
Expand Up @@ -17,8 +17,8 @@
"@mdx-js/mdx": "^1.0.0",
"@mdx-js/react": "^1.0.0",
"gatsby": "^4.0.0-next",
"react": "^16.9.0 || ^17.0.0",
"react-dom": "^16.9.0 || ^17.0.0"
"react": "^16.9.0 || ^17.0.0 || ^18.0.0",
"react-dom": "^16.9.0 || ^17.0.0 || ^18.0.0"
},
"dependencies": {
"@babel/core": "^7.15.5",
Expand Down
4 changes: 2 additions & 2 deletions packages/gatsby-plugin-netlify-cms/package.json
Expand Up @@ -38,8 +38,8 @@
"peerDependencies": {
"gatsby": "^4.0.0-next",
"netlify-cms-app": "^2.9.0",
"react": "^16.9.0 || ^17.0.0",
"react-dom": "^16.9.0 || ^17.0.0",
"react": "^16.9.0 || ^17.0.0 || ^18.0.0",
"react-dom": "^16.9.0 || ^17.0.0 || ^18.0.0",
"webpack": "^5.0.0"
},
"repository": {
Expand Down
4 changes: 2 additions & 2 deletions packages/gatsby-plugin-offline/package.json
Expand Up @@ -36,8 +36,8 @@
"main": "index.js",
"peerDependencies": {
"gatsby": "^4.0.0-next",
"react": "^16.9.0 || ^17.0.0",
"react-dom": "^16.9.0 || ^17.0.0"
"react": "^16.9.0 || ^17.0.0 || ^18.0.0",
"react-dom": "^16.9.0 || ^17.0.0 || ^18.0.0"
},
"repository": {
"type": "git",
Expand Down
4 changes: 2 additions & 2 deletions packages/gatsby-plugin-sitemap/package.json
Expand Up @@ -31,8 +31,8 @@
"main": "index.js",
"peerDependencies": {
"gatsby": "^4.0.0-next",
"react": "^16.9.0 || ^17.0.0",
"react-dom": "^16.9.0 || ^17.0.0"
"react": "^16.9.0 || ^17.0.0 || ^18.0.0",
"react-dom": "^16.9.0 || ^17.0.0 || ^18.0.0"
},
"repository": {
"type": "git",
Expand Down
4 changes: 2 additions & 2 deletions packages/gatsby-plugin-styled-components/package.json
Expand Up @@ -26,8 +26,8 @@
"peerDependencies": {
"babel-plugin-styled-components": ">1.5.0",
"gatsby": "^4.0.0-next",
"react": "^16.9.0 || ^17.0.0",
"react-dom": "^16.9.0 || ^17.0.0",
"react": "^16.9.0 || ^17.0.0 || ^18.0.0",
"react-dom": "^16.9.0 || ^17.0.0 || ^18.0.0",
"styled-components": ">=2.0.0"
},
"repository": {
Expand Down
4 changes: 2 additions & 2 deletions packages/gatsby-plugin-typography/package.json
Expand Up @@ -30,8 +30,8 @@
"main": "index.js",
"peerDependencies": {
"gatsby": "^4.0.0-next",
"react": "^16.9.0 || ^17.0.0",
"react-dom": "^16.9.0 || ^17.0.0",
"react": "^16.9.0 || ^17.0.0 || ^18.0.0",
"react-dom": "^16.9.0 || ^17.0.0 || ^18.0.0",
"react-typography": "^0.16.1 || ^1.0.0-alpha.0",
"typography": "^0.16.0 || ^1.0.0-alpha.0"
},
Expand Down
4 changes: 2 additions & 2 deletions packages/gatsby-react-router-scroll/package.json
Expand Up @@ -26,8 +26,8 @@
"main": "index.js",
"peerDependencies": {
"@gatsbyjs/reach-router": "^1.3.5",
"react": "^16.9.0 || ^17.0.0",
"react-dom": "^16.9.0 || ^17.0.0"
"react": "^16.9.0 || ^17.0.0 || ^18.0.0",
"react-dom": "^16.9.0 || ^17.0.0 || ^18.0.0"
},
"repository": {
"type": "git",
Expand Down
4 changes: 2 additions & 2 deletions packages/gatsby-remark-autolink-headers/package.json
Expand Up @@ -30,8 +30,8 @@
"main": "index.js",
"peerDependencies": {
"gatsby": "^4.0.0-next",
"react": "^16.9.0 || ^17.0.0",
"react-dom": "^16.9.0 || ^17.0.0"
"react": "^16.9.0 || ^17.0.0 || ^18.0.0",
"react-dom": "^16.9.0 || ^17.0.0 || ^18.0.0"
},
"repository": {
"type": "git",
Expand Down