From 38a3c7e5438c08b9036c3988e8932c2457bfb7b6 Mon Sep 17 00:00:00 2001 From: Taku Amano Date: Sun, 27 Oct 2024 21:07:22 +0900 Subject: [PATCH] fix(jsx/dom): fix `memo` for DOM renderer --- src/jsx/base.ts | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/src/jsx/base.ts b/src/jsx/base.ts index a13186814..c2ddfa296 100644 --- a/src/jsx/base.ts +++ b/src/jsx/base.ts @@ -1,7 +1,7 @@ import { raw } from '../helper/html' import { escapeToBuffer, resolveCallbackSync, stringBufferToString } from '../utils/html' import type { HtmlEscaped, HtmlEscapedString, StringBufferWithCallbacks } from '../utils/html' -import { DOM_RENDERER } from './constants' +import { DOM_RENDERER, DOM_MEMO } from './constants' import type { Context } from './context' import { createContext, globalContexts, useContext } from './context' import { domRenderers } from './intrinsic-element/common' @@ -346,7 +346,7 @@ export const jsxFn = ( } } -const shallowEqual = (a: Props, b: Props): boolean => { +export const shallowEqual = (a: Props, b: Props): boolean => { if (a === b) { return true } @@ -382,13 +382,21 @@ export const memo = ( ): FC => { let computed: ReturnType> = null let prevProps: T | undefined = undefined - return ((props) => { + const wrapper: MemorableFC = ((props: T) => { if (prevProps && !propsAreEqual(prevProps, props)) { computed = null } prevProps = props return (computed ||= component(props)) - }) as FC + }) as MemorableFC + + // This function is for toString(), but it can also be used for DOM renderer. + // So, set DOM_MEMO and DOM_RENDERER for DOM renderer. + wrapper[DOM_MEMO] = propsAreEqual + // eslint-disable-next-line @typescript-eslint/no-explicit-any + ;(wrapper as any)[DOM_RENDERER] = component + + return wrapper as FC } export const Fragment = ({