Skip to content

Commit

Permalink
fix(gatsby-plugin-image): Force render if props have changed (#30491) (
Browse files Browse the repository at this point in the history
…#30565)

* fix(gatsby-plugin-image): Force render if props have changed

* Add comments

(cherry picked from commit e584b8a)

Co-authored-by: Matt Kane <matt@gatsbyjs.com>
  • Loading branch information
vladar and ascorbic committed Mar 30, 2021
1 parent 21804e3 commit 9b8196b
Show file tree
Hide file tree
Showing 2 changed files with 13 additions and 6 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,10 @@ class GatsbyImageHydrator extends Component<
HTMLImageElement | undefined
>()
hydrated: MutableRefObject<boolean> = { current: false }
forceRender: MutableRefObject<boolean> = {
// In dev we use render not hydrate, to avoid hydration warnings
current: process.env.NODE_ENV === `development`,
}
lazyHydrator: () => void | null = null
ref = createRef<HTMLImageElement>()
unobserveRef: Unobserver
Expand Down Expand Up @@ -101,7 +105,8 @@ class GatsbyImageHydrator extends Component<
...props,
},
this.root,
this.hydrated
this.hydrated,
this.forceRender
)
})
}
Expand Down Expand Up @@ -132,7 +137,10 @@ class GatsbyImageHydrator extends Component<

shouldComponentUpdate(nextProps, nextState): boolean {
let hasChanged = false

if (!this.state.isLoading && nextState.isLoading && !nextState.isLoaded) {
// Props have changed between SSR and hydration, so we need to force render instead of hydrate
this.forceRender.current = true
}
// this check mostly means people do not have the correct ref checks in place, we want to reset some state to suppport loading effects
if (this.props.image.images !== nextProps.image.images) {
// reset state, we'll rely on intersection observer to reload
Expand Down
7 changes: 3 additions & 4 deletions packages/gatsby-plugin-image/src/components/lazy-hydrate.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,6 @@ type LazyHydrateProps = Omit<GatsbyImageProps, "as" | "style" | "className"> & {
ref: MutableRefObject<HTMLImageElement | undefined>
}

const IS_DEV = process.env.NODE_ENV === `development`

export function lazyHydrate(
{
image,
Expand All @@ -32,7 +30,8 @@ export function lazyHydrate(
...props
}: LazyHydrateProps,
root: MutableRefObject<HTMLElement | undefined>,
hydrated: MutableRefObject<boolean>
hydrated: MutableRefObject<boolean>,
forceHydrate: MutableRefObject<boolean>
): (() => void) | null {
const {
width,
Expand Down Expand Up @@ -85,7 +84,7 @@ export function lazyHydrate(
)

// Force render to mitigate "Expected server HTML to contain a matching" in develop
const doRender = hydrated.current || IS_DEV ? render : hydrate
const doRender = hydrated.current || forceHydrate.current ? render : hydrate
doRender(component, root.current)
hydrated.current = true

Expand Down

0 comments on commit 9b8196b

Please sign in to comment.