fix(provider): avoid stale styles when toggling dark/light theme#9538
Conversation
Summary of ChangesHello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed! This pull request addresses an issue in v3 where styles would not refresh immediately upon switching themes or tokens, leading to stale visual states. The solution involves enhancing the style registration mechanism to be aware of theme and token changes, ensuring that styles are correctly re-registered and applied when these dynamic properties are updated. Highlights
🧠 New Feature in Public Preview: You can now enable Memory to help Gemini Code Assist learn from your team's feedback. This makes future code reviews more consistent and personalized to your project's style. Click here to enable Memory in your admin console. Changelog
Using Gemini Code AssistThe full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips. Invoking Gemini You can request assistance from Gemini at any point by creating a comment using either
Customization To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a Limitations & Feedback Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here. You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension. Footnotes
|
📝 WalkthroughWalkthrough将样式注册路径由固定组件名替换为包含 componentName、hashId、theme.id、token._tokenKey 与 token.themeId 的复合 stylePath,并通过 styleKey 与 styleVersionRef 跟踪主题/token 变化,返回值中保留并透出 wrapSSR 和 hashId。 Changes
Sequence Diagram(s)(本次变更为单文件内部的样式路径与版本管理,无需序列图) Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes 兔子的诗
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Code Review
This pull request effectively addresses the issue of stale styles during theme changes by incorporating theme-sensitive keys into the style registration path. The logic is sound and directly solves the described problem. I have one minor suggestion to improve code clarity and correctness in how a theme property is accessed.
src/provider/useStyle/index.ts
Outdated
| const stylePath = [ | ||
| componentName, | ||
| hashId, | ||
| (theme as any)?.id, |
There was a problem hiding this comment.
ae55fc4 to
839a986
Compare
There was a problem hiding this comment.
🧹 Nitpick comments (1)
src/provider/useStyle/index.ts (1)
121-127: 添加注释说明缓存键组成部分来提高代码可读性当前代码使用
theme.id、token._tokenKey和token.themeId作为样式缓存键。其中theme.id是@ant-design/cssinjs的文档化属性(用于缓存的唯一主题标识),token.themeId已在ProAliasToken中定义,但token._tokenKey是 cssinjs 的内部属性。虽然这是 antd 推荐的缓存失效模式,但添加注释说明各部分的作用会增强代码清晰度。💡 建议添加注释
+ // Make path theme-sensitive so token/theme switches trigger style re-registration. + // Properties: theme.id (cssinjs theme identifier), token._tokenKey (internal token cache key), token.themeId (ProAliasToken custom id) const stylePath = [ componentName, hashId, (theme as any)?.id, (token as any)?._tokenKey, (token as any)?.themeId, ].filter(Boolean);🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/provider/useStyle/index.ts` around lines 121 - 127, Add a brief inline comment above the stylePath construction explaining each part of the cache key: componentName (component-specific prefix), hashId (compiled/style hash), (theme as any)?.id (documented unique theme id from `@ant-design/cssinjs`), (token as any)?._tokenKey (internal cssinjs token key used to expire caches), and (token as any)?.themeId (token's theme identifier defined on ProAliasToken); place this comment near the stylePath declaration so future readers understand why each field is included for cache invalidation and uniqueness.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Nitpick comments:
In `@src/provider/useStyle/index.ts`:
- Around line 121-127: Add a brief inline comment above the stylePath
construction explaining each part of the cache key: componentName
(component-specific prefix), hashId (compiled/style hash), (theme as any)?.id
(documented unique theme id from `@ant-design/cssinjs`), (token as any)?._tokenKey
(internal cssinjs token key used to expire caches), and (token as any)?.themeId
(token's theme identifier defined on ProAliasToken); place this comment near the
stylePath declaration so future readers understand why each field is included
for cache invalidation and uniqueness.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: f8cdfe6c-d8c5-4e2b-86b6-f03f0736605a
📒 Files selected for processing (1)
src/provider/useStyle/index.ts
There was a problem hiding this comment.
🧹 Nitpick comments (1)
src/provider/useStyle/index.ts (1)
119-127: 整体方案正确,能够解决主题切换时样式不刷新的问题。通过将
stylePath与theme.id、hashId和themeId关联,确保主题切换时触发样式重新注册,符合 PR 目标。一个小建议:第 126 行对
themeId的类型断言是多余的,因为ProAliasToken类型(第 48 行)已经定义了themeId: number。可以简化为:♻️ 可选优化
const stylePath = [ componentName, hashId, (theme as any).id, (token as any)?._tokenKey, - (token as any)?.themeId, + token.themeId, ].filter(Boolean);🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/provider/useStyle/index.ts` around lines 119 - 127, The code builds stylePath with an unnecessary type assertion for themeId; update the stylePath construction to use token?.themeId (remove the (token as any)? cast) so it relies on the declared ProAliasToken.themeId type—i.e., replace (token as any)?.themeId with token?.themeId in the stylePath array (leave other casts unchanged).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Nitpick comments:
In `@src/provider/useStyle/index.ts`:
- Around line 119-127: The code builds stylePath with an unnecessary type
assertion for themeId; update the stylePath construction to use token?.themeId
(remove the (token as any)? cast) so it relies on the declared
ProAliasToken.themeId type—i.e., replace (token as any)?.themeId with
token?.themeId in the stylePath array (leave other casts unchanged).
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 9132358e-7345-4c17-a5c9-7cefbd1af9f4
📒 Files selected for processing (1)
src/provider/useStyle/index.ts
839a986 to
351dd71
Compare
1a95a83 to
76a1a02
Compare
76a1a02 to
ddd18f1
Compare
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@src/provider/useStyle/index.ts`:
- Around line 122-146: styleKey currently can't detect Pro token changes because
useStyle reads the finalToken from ProProvider (finalToken) which lacks the
internal _tokenKey; update useStyle to derive its key from the cached token
returned by useCacheToken (the value that contains _tokenKey) instead of the
finalToken so that (token as any)?._tokenKey becomes a real value, and ensure
stylePath/styleVersionRef/lastStyleKeyRef logic uses that cached token;
additionally extend the ProAliasToken/type definitions to include _tokenKey and
ensure theme.id is typed (remove as any casts) so changes to Pro token update
styleKey and trigger useStyleRegister correctly.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: aeb0a832-32cf-4ef0-9af6-00889d9b176a
📒 Files selected for processing (1)
src/provider/useStyle/index.ts
| const styleKey = [ | ||
| hashId, | ||
| (theme as any).id, | ||
| (token as any)?._tokenKey, | ||
| (token as any)?.themeId, | ||
| ] | ||
| .filter(Boolean) | ||
| .join('-'); | ||
|
|
||
| const lastStyleKeyRef = useRef<string>(''); | ||
| const styleVersionRef = useRef(0); | ||
| if (lastStyleKeyRef.current !== styleKey) { | ||
| styleVersionRef.current += 1; | ||
| lastStyleKeyRef.current = styleKey; | ||
| } | ||
|
|
||
| const stylePath = [componentName, styleKey, styleVersionRef.current].filter( | ||
| Boolean, | ||
| ); | ||
|
|
||
| useStyleRegister( | ||
| { | ||
| theme: theme as any, | ||
| token, | ||
| path: [componentName], | ||
| path: stylePath, |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "=== Examining token flow and _tokenKey usage ==="
rg -n -C4 'const finalToken|useCacheToken<ProAliasToken>|token:\s*finalToken as any|_tokenKey|themeId' \
src/provider/index.tsx src/provider/useStyle/index.tsRepository: ant-design/pro-components
Length of output: 1878
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "=== Checking ProConfigContext definition and token property type ==="
rg -n -B5 -A5 'createContext|ProConfigContext' src/provider/index.tsx | head -60
echo ""
echo "=== Checking useCacheToken return type and _tokenKey ==="
rg -n 'useCacheToken.*ProAliasToken' src/provider/index.tsx -A10 | head -40Repository: ant-design/pro-components
Length of output: 2064
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "=== Checking useStyle hook complete implementation ==="
sed -n '1,150p' src/provider/useStyle/index.ts | cat -nRepository: ant-design/pro-components
Length of output: 5229
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "=== Finding proConfigContextValue construction ==="
rg -n 'proConfigContextValue\s*=' src/provider/index.tsx -B5 -A20 | head -80Repository: ant-design/pro-components
Length of output: 828
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "=== Checking what useCacheToken returns (checking _tokenKey and typing) ==="
rg -n '_tokenKey|useCacheToken' src/provider/index.tsx -B2 -A2 | head -50
echo ""
echo "=== Checking ProAliasToken and related type definitions ==="
grep -n '_tokenKey\|themeId' src/provider/useStyle/index.ts src/provider/typing/*.ts 2>/dev/null || echo "Type file not found in expected location"Repository: ant-design/pro-components
Length of output: 813
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "=== Find complete ProProvider context value assignment ==="
sed -n '280,370p' src/provider/index.tsx | cat -nRepository: ant-design/pro-components
Length of output: 2904
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "=== Checking _tokenKey origin in cssinjs or antd ==="
rg -n '_tokenKey' --type ts --type tsx | head -30
echo ""
echo "=== Verify finalToken structure vs useCacheToken return ==="
rg -n 'finalToken|useCacheToken' src/provider/index.tsx | grep -E '(const |finalToken|useCacheToken)'Repository: ant-design/pro-components
Length of output: 166
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "=== Check type definitions in ProConfigContextValue ==="
rg -n 'ConfigContextPropsType|ProConfigContext' src/provider -B3 -A15 | head -100Repository: ant-design/pro-components
Length of output: 4895
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "=== Verify what token object should contain in type system ==="
rg -n 'type ProAliasToken|interface.*Token' src/provider/useStyle/index.ts -A10 | head -40Repository: ant-design/pro-components
Length of output: 394
styleKey 无法真正依赖 Pro token 变化
useStyle 从 ProProvider context 获取的 token 实际是 finalToken(见 src/provider/index.tsx 第 347 行),而不是 useCacheToken 的返回值。因为 ProAliasToken 类型定义(useStyle/index.ts 第 46-54 行)中并不包含 _tokenKey 属性,所以第 125 行的 (token as any)?._tokenKey 在此上下文中必然为 undefined。这导致 stylePath 主要只依赖 hashId 和 theme.id,无法覆盖"同一 theme 下仅 Pro token 更新"的场景。
建议改为传递 useCacheToken 返回的 token(该 token 包含 _tokenKey),或采用其他确保对 Pro token 变化敏感的稳定键。同时补充 _tokenKey 和 theme.id 等属性的类型定义,避免新增 as any 导致类型检查失效。
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@src/provider/useStyle/index.ts` around lines 122 - 146, styleKey currently
can't detect Pro token changes because useStyle reads the finalToken from
ProProvider (finalToken) which lacks the internal _tokenKey; update useStyle to
derive its key from the cached token returned by useCacheToken (the value that
contains _tokenKey) instead of the finalToken so that (token as any)?._tokenKey
becomes a real value, and ensure stylePath/styleVersionRef/lastStyleKeyRef logic
uses that cached token; additionally extend the ProAliasToken/type definitions
to include _tokenKey and ensure theme.id is typed (remove as any casts) so
changes to Pro token update styleKey and trigger useStyleRegister correctly.
ddd18f1 to
20ca73d
Compare
|
@afc163 @chenshuai2144 Friendly ping: this PR fixes #9373 (dark/light theme toggle stale style issue in ) and has been locally verified with light -> dark -> light toggles. Could you help review/merge when convenient? Thanks! 🙏 |
|
Correction: this PR fixes #9373 (dark/light theme toggle stale style issue in @afc163 @chenshuai2144 Could you help review/merge when convenient? Thanks! 🙏 |
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## master #9538 +/- ##
==========================================
- Coverage 91.68% 91.64% -0.05%
==========================================
Files 309 309
Lines 11215 11233 +18
Branches 4179 4184 +5
==========================================
+ Hits 10283 10295 +12
- Misses 816 821 +5
- Partials 116 117 +1 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
对 antd 的 cssinjs 不熟,可能无法帮上忙,不过我会尝试一下 :) |


Summary
wrapSSRidentity behavior unchangedBackground
useStylein provider registers styles viauseStyleRegisterwith side effects. With a static path key, switching theme could reuse stale style cache/order and make styles not fully recover when toggling back.Fix
styleKeyfromhashId,theme.id,token._tokenKey, andtoken.themeId[componentName, styleKey, version]touseStyleRegisterRepro
Related
Summary by CodeRabbit
发布说明