Skip to content

Commit

Permalink
✨pref: improve memorization
Browse files Browse the repository at this point in the history
  • Loading branch information
Wxh16144 committed Oct 23, 2024
1 parent 1f71391 commit 1186145
Show file tree
Hide file tree
Showing 2 changed files with 78 additions and 66 deletions.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -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": {
Expand Down
143 changes: 77 additions & 66 deletions src/factories/createStyles/index.ts
Original file line number Diff line number Diff line change
@@ -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 {
Expand Down Expand Up @@ -52,76 +54,85 @@ export const createStylesFactory =

const responsiveMap = useMediaQueryMap();

const styles = useMemo(() => {
let tempStyles: ReturnStyleToUse<Input>;

// 函数场景
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<Input>;

// 函数场景
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]);
Expand Down

0 comments on commit 1186145

Please sign in to comment.