Closed fz6m closed 1 month ago
antd 的插件中提供了一个 useAntdConfigSetter 的功能,它把 antd Config Provider 的配置管理成 state ,从而可以便捷的改变 antd Config Provider ,比如切换主题。来源:https://github.com/umijs/umi/pull/11856
useAntdConfigSetter
但这个功能和 model 插件一起使用时,会发生冲突,复现代码的大致例子:
const setAntdConfig = useAntdConfigSetter() const changeTheme = () => { const { themeMode, antdToken } = getThemeToken(); const targetThemeMode = themeMode === 'dark' ? 'light' : 'dark'; // 将变量写入localStorage setThemeMode(targetThemeMode); const algorithm = targetThemeMode === 'light' ? [defaultAlgorithm] : [darkAlgorithm]; const antdTheme: ThemeConfig = { algorithm }; if (antdToken) { antdTheme.token = antdToken; } setAntdConfig({ theme: antdTheme });
注:不必拘泥于这段代码的写法,只要在 model 插件开启的时候,使用 setAntdConfig 去改变 antd 的主题,即可复现。
setAntdConfig
反馈来源:https://github.com/umijs/umi/discussions/12287
经过初次探索,冲突原因大致如下:
antd config provider 的更新导致整个组件树重新渲染了,走到 model 的那一层 context 的时候,组件重新挂载,导致在重渲染的过程中执行了 setState (因为 model 的 context 里在第一次挂载的时候,急切的需要执行一次获取初始值的操作,而这个操作在执行的时候,正好处于 antd 重渲染的流程中),react 不允许这种行为,所以报错了。
因为 antd 的 setAntdConfig 其实是一种正确的 react 使用方式,而 model 的源码比较古老且 hack ,所以让 setAntdConfig 妥协不如修正 model ,所以期望能修正 model 源码来兼容这种用法解决,若实在无法修复,则退而次之再看看如何调整 setAntdConfig 妥协。
目前没有想到较好的方式解决,欢迎任何人贡献 PR
已有解决方案。
cc @xiaohuoni
没复现出来,谁帮忙给一下重现一下。 https://github.com/xiaohuoni/max-model-antd
知道原因了,你的这个 demo 让我找到了真正原因👍。
说明
antd 的插件中提供了一个
useAntdConfigSetter
的功能,它把 antd Config Provider 的配置管理成 state ,从而可以便捷的改变 antd Config Provider ,比如切换主题。来源:https://github.com/umijs/umi/pull/11856但这个功能和 model 插件一起使用时,会发生冲突,复现代码的大致例子:
注:不必拘泥于这段代码的写法,只要在 model 插件开启的时候,使用
setAntdConfig
去改变 antd 的主题,即可复现。反馈来源:https://github.com/umijs/umi/discussions/12287
原因
经过初次探索,冲突原因大致如下:
antd config provider 的更新导致整个组件树重新渲染了,走到 model 的那一层 context 的时候,组件重新挂载,导致在重渲染的过程中执行了 setState (因为 model 的 context 里在第一次挂载的时候,急切的需要执行一次获取初始值的操作,而这个操作在执行的时候,正好处于 antd 重渲染的流程中),react 不允许这种行为,所以报错了。
期望的解决方式
因为 antd 的setAntdConfig
其实是一种正确的 react 使用方式,而 model 的源码比较古老且 hack ,所以让setAntdConfig
妥协不如修正 model ,所以期望能修正 model 源码来兼容这种用法解决,若实在无法修复,则退而次之再看看如何调整setAntdConfig
妥协。目前没有想到较好的方式解决,欢迎任何人贡献 PR已有解决方案。
cc @xiaohuoni