From 1186145b187c1cb17f34794327d893ea746c8302 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=F0=9D=91=BE=F0=9D=92=96=F0=9D=92=99=F0=9D=92=89?= Date: Wed, 23 Oct 2024 19:08:43 +0800 Subject: [PATCH 1/3] =?UTF-8?q?=E2=9C=A8pref:=20improve=20memorization?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package.json | 1 + src/factories/createStyles/index.ts | 143 +++++++++++++++------------- 2 files changed, 78 insertions(+), 66 deletions(-) diff --git a/package.json b/package.json index 76b7150c..338f9bcd 100644 --- a/package.json +++ b/package.json @@ -76,6 +76,7 @@ "@emotion/react": "^11.11.4", "@emotion/serialize": "^1.1.3", "@emotion/utils": "^1.2.1", + "rc-util": "^5.43.0", "use-merge-value": "^1.2.0" }, "devDependencies": { diff --git a/src/factories/createStyles/index.ts b/src/factories/createStyles/index.ts index bc178f47..5c795eb8 100644 --- a/src/factories/createStyles/index.ts +++ b/src/factories/createStyles/index.ts @@ -1,4 +1,6 @@ -import { Context, useContext, useMemo } from 'react'; +import useMemo from 'rc-util/es/hooks/useMemo'; +import isEqual from 'rc-util/lib/isEqual'; +import React, { Context, useContext } from 'react'; import { Emotion, createCSS, serializeCSS } from '@/core'; import type { @@ -52,76 +54,85 @@ export const createStylesFactory = const responsiveMap = useMediaQueryMap(); - const styles = useMemo(() => { - let tempStyles: ReturnStyleToUse; - - // 函数场景 - if (styleOrGetStyle instanceof Function) { - const { stylish, appearance, isDarkMode, prefixCls, iconPrefixCls, ...token } = theme; - - // 创建响应式断点选择器的工具函数 - // @ts-ignore - const responsive: ResponsiveUtil = (styles) => - convertResponsiveStyleToString(styles, responsiveMap); - // 并赋予其相应的断点工具 - Object.assign(responsive, responsiveMap); - - tempStyles = styleOrGetStyle( - { - token, - stylish, - appearance, - isDarkMode, - prefixCls, - iconPrefixCls, - // 工具函数们 - cx, - css: serializeCSS, - responsive, - }, - props!, - ) as any; - } - // 没有函数时直接就是 object 或者 string - else { - tempStyles = styleOrGetStyle as any; - } - - if (typeof tempStyles === 'object') { - // 判断是否是用 reactCSS 生成的 - if (isReactCssResult(tempStyles)) { - // 如果是用 reactCss 生成的话,需要用 className 的 css 做一层转换 - tempStyles = toClassName(tempStyles) as any; - } else { - // 不是的话就是直接是 复合的 css object - tempStyles = Object.fromEntries( - Object.entries(tempStyles).map(([key, value]) => { - // 这里做两道转换: - // 1. 如果是用 babel 插件,则将样式的 label 设置为当前文件名 + key - // 2. 如果是 SerializedStyles ,将其用 cx 包一下转换成 className - - const label = usingBabel ? `${styleFileName}-${key}` : undefined; - - // 这里有可能是 { a : css` color:red ` } 也可能是 { b: { color:"blue" } } 这样的写法 - if (typeof value === 'object') { - if (usingBabel) { - return [key, toClassName(value, `label:${label}`) as any]; - } + const styles = useMemo( + () => { + let tempStyles: ReturnStyleToUse; + + // 函数场景 + if (styleOrGetStyle instanceof Function) { + const { stylish, appearance, isDarkMode, prefixCls, iconPrefixCls, ...token } = theme; + + // 创建响应式断点选择器的工具函数 + // @ts-ignore + const responsive: ResponsiveUtil = (styles) => + convertResponsiveStyleToString(styles, responsiveMap); + // 并赋予其相应的断点工具 + Object.assign(responsive, responsiveMap); + + tempStyles = styleOrGetStyle( + { + token, + stylish, + appearance, + isDarkMode, + prefixCls, + iconPrefixCls, + // 工具函数们 + cx, + css: serializeCSS, + responsive, + }, + props!, + ) as any; + } + // 没有函数时直接就是 object 或者 string + else { + tempStyles = styleOrGetStyle as any; + } - return [key, toClassName(value) as any]; - } + if (typeof tempStyles === 'object') { + // 判断是否是用 reactCSS 生成的 + if (isReactCssResult(tempStyles)) { + // 如果是用 reactCss 生成的话,需要用 className 的 css 做一层转换 + tempStyles = toClassName(tempStyles) as any; + } else { + // 不是的话就是直接是 复合的 css object + tempStyles = Object.fromEntries( + Object.entries(tempStyles).map(([key, value]) => { + // 这里做两道转换: + // 1. 如果是用 babel 插件,则将样式的 label 设置为当前文件名 + key + // 2. 如果是 SerializedStyles ,将其用 cx 包一下转换成 className + + const label = usingBabel ? `${styleFileName}-${key}` : undefined; + + // 这里有可能是 { a : css` color:red ` } 也可能是 { b: { color:"blue" } } 这样的写法 + if (typeof value === 'object') { + if (usingBabel) { + return [key, toClassName(value, `label:${label}`) as any]; + } + + return [key, toClassName(value) as any]; + } - // 这里只可能是 { c: cx(css`color:red`) } , 或者 d: 'abcd' 这样的写法 - return [key, value]; - }), - ) as any; + // 这里只可能是 { c: cx(css`color:red`) } , 或者 d: 'abcd' 这样的写法 + return [key, value]; + }), + ) as any; + } } - } - return tempStyles; - }, [props, theme]); + return tempStyles; + }, + [props, theme], + (prev: any[], next: any[]) => + prev.some((prevDep, index) => { + const nextDep = next[index]; + + return !isEqual(prevDep, nextDep, true); + }), + ); - return useMemo(() => { + return React.useMemo(() => { const { prefixCls, iconPrefixCls, ...res } = theme; return { styles, cx, theme: res, prefixCls, iconPrefixCls }; }, [styles, theme]); From 957430ac587b9fd3a3765859720973c11f5f7911 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=F0=9D=91=BE=F0=9D=92=96=F0=9D=92=99=F0=9D=92=89?= Date: Thu, 24 Oct 2024 11:28:54 +0800 Subject: [PATCH 2/3] chore: fix import path --- src/factories/createStyles/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/factories/createStyles/index.ts b/src/factories/createStyles/index.ts index 5c795eb8..84e45d78 100644 --- a/src/factories/createStyles/index.ts +++ b/src/factories/createStyles/index.ts @@ -1,4 +1,4 @@ -import useMemo from 'rc-util/es/hooks/useMemo'; +import useMemo from 'rc-util/lib/hooks/useMemo'; import isEqual from 'rc-util/lib/isEqual'; import React, { Context, useContext } from 'react'; From 70e0bc5670cb4924a3a3f5d8cb679eb9e2c409d5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=F0=9D=91=BE=F0=9D=92=96=F0=9D=92=99=F0=9D=92=89?= Date: Thu, 14 Nov 2024 18:10:00 +0800 Subject: [PATCH 3/3] chore: update --- src/factories/createStyles/index.ts | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/src/factories/createStyles/index.ts b/src/factories/createStyles/index.ts index 84e45d78..2bc226a7 100644 --- a/src/factories/createStyles/index.ts +++ b/src/factories/createStyles/index.ts @@ -1,6 +1,6 @@ import useMemo from 'rc-util/lib/hooks/useMemo'; import isEqual from 'rc-util/lib/isEqual'; -import React, { Context, useContext } from 'react'; +import { Context, useContext } from 'react'; import { Emotion, createCSS, serializeCSS } from '@/core'; import type { @@ -124,17 +124,16 @@ export const createStylesFactory = return tempStyles; }, [props, theme], - (prev: any[], next: any[]) => - prev.some((prevDep, index) => { - const nextDep = next[index]; - - return !isEqual(prevDep, nextDep, true); - }), + (prev, next) => !isEqual(prev[0], next[0], true) || prev[1] !== next[1], ); - return React.useMemo(() => { - const { prefixCls, iconPrefixCls, ...res } = theme; - return { styles, cx, theme: res, prefixCls, iconPrefixCls }; - }, [styles, theme]); + return useMemo( + () => { + const { prefixCls, iconPrefixCls, ...res } = theme; + return { styles, cx, theme: res, prefixCls, iconPrefixCls }; + }, + [styles, theme], + (prev, next) => !isEqual(prev[0], next[0], true) || prev[1] !== next[1], + ); }; };