Skip to content

Commit

Permalink
Fix caching of null result of buildComponentRenderResult (#6352)
Browse files Browse the repository at this point in the history
**Problem:**
When a component returns null, it is rerendered all the time.

**Root cause:**
The problem is in the caching of the result of
`buildComponentRenderResult`.
The cache is initialized with a `null` value, so when the value is
`null` we rerun `buildComponentRenderResult`
However, the value can be null just because the component renders
nothing.

**Commit Details:**

- Created a new type for the `buildResult` type which includes an
external value for the non-initialized state.

**Manual Tests:**
I hereby swear that:

- [x] I opened a hydrogen project and it loaded
- [x] I could navigate to various routes in Preview mode
  • Loading branch information
gbalint authored Sep 11, 2024
1 parent a2d6ac7 commit d3a7bb8
Showing 1 changed file with 34 additions and 6 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,25 @@ function tryToGetInstancePath(
}
}

type EmptyBuildResult = {
type: 'EMPTY_BUILD_RESULT'
}

type RenderedBuildResult = {
type: 'RENDERED_BUILD_RESULT'
result: React.ReactElement | null
}

type BuildResult = EmptyBuildResult | RenderedBuildResult

function emptyBuildResult(): EmptyBuildResult {
return { type: 'EMPTY_BUILD_RESULT' }
}

function renderedBuildResult(result: React.ReactElement | null): RenderedBuildResult {
return { type: 'RENDERED_BUILD_RESULT', result: result }
}

export function createComponentRendererComponent(params: {
topLevelElementName: string | null
filePath: string
Expand Down Expand Up @@ -247,7 +266,7 @@ export function createComponentRendererComponent(params: {
filePathMappings: rerenderUtopiaContext.filePathMappings,
}

const buildResult = React.useRef<React.ReactElement | null>(null)
const buildResult = React.useRef<BuildResult>(emptyBuildResult())

let earlyReturn: EarlyReturn | null = null
if (utopiaJsxComponent.arbitraryJSBlock != null) {
Expand Down Expand Up @@ -299,11 +318,11 @@ export function createComponentRendererComponent(params: {
break
case 'EARLY_RETURN_VOID':
earlyReturn = arbitraryBlockResult
buildResult.current = undefined as any
buildResult.current = renderedBuildResult(undefined as any)
break
case 'EARLY_RETURN_RESULT':
earlyReturn = arbitraryBlockResult
buildResult.current = arbitraryBlockResult.result as any
buildResult.current = renderedBuildResult(arbitraryBlockResult.result as any)
break
default:
assertNever(arbitraryBlockResult)
Expand Down Expand Up @@ -350,10 +369,19 @@ export function createComponentRendererComponent(params: {
null,
)
}
} else if (shouldUpdate() || buildResult.current === null) {
buildResult.current = buildComponentRenderResult(utopiaJsxComponent.rootElement)
} else if (shouldUpdate() || buildResult.current.type === 'EMPTY_BUILD_RESULT') {
buildResult.current = renderedBuildResult(
buildComponentRenderResult(utopiaJsxComponent.rootElement),
)
}
switch (buildResult.current.type) {
case 'EMPTY_BUILD_RESULT':
return null
case 'RENDERED_BUILD_RESULT':
return buildResult.current.result
default:
assertNever(buildResult.current)
}
return buildResult.current
}
Component.displayName = `ComponentRenderer(${params.topLevelElementName})`
Component.topLevelElementName = params.topLevelElementName
Expand Down

0 comments on commit d3a7bb8

Please sign in to comment.