NextJs - antd5 降级兼容方案
前言
目前antd5
对于SSR
的兼容还有各方面都是很不错的,比如性能、UI设计等,不过,我们作为开发人员,在使用antd5
作为UI组件库的时候,还需要考虑版本兼容问题,这里就说明下NextJs
中如何进行antd5
的降级。
和本篇内容有关的前序文章:NextJs - SSR渲染解决antd首屏加载CSS样式的闪烁问题
官方的:参考文档
一. 降级解决方案
降级主要针对两个方向:
- 静态组件:
message
、Modal
等组件 - 非静态组件:
Row
、这类常规的组件。
antd
中可以直接 message.xxx,Modal.xxx,notification.xxx
静态方法调用展示对应的UI
,这类弹出类的组件,是脱离了root
节点之外插入的,因此他们在低版本的浏览器下可能会不生效,例如Modal.info
函数,在chrome87版本就会不生效
1.1 解决 message 等通知静态方法的样式丢失问题
创建组件:MyContainer
,参考:官网解决方式
import { App } from 'antd';
import type { MessageInstance } from 'antd/es/message/interface';
import type { ModalStaticFunctions } from 'antd/es/modal/confirm';
import type { NotificationInstance } from 'antd/es/notification/interface';
let message: MessageInstance;
let notification: NotificationInstance;
let modal: Omit<ModalStaticFunctions, 'warn'>;
export default function MyContainer({ children }: { children: React.ReactNode }) {
const staticFunction = App.useApp();
message = staticFunction.message;
modal = staticFunction.modal;
notification = staticFunction.notification;
return children;
}
export { message, modal, notification };
1.1 解决非静态的样式兼容
我们创建组件:RootStyleRegistry
'use client';
import { createCache, extractStyle, legacyLogicalPropertiesTransformer, StyleProvider } from '@ant-design/cssinjs';
import { App } from 'antd';
import { useServerInsertedHTML } from 'next/navigation';
import { useState } from 'react';
import MyContainer from '.MyContainer';
export const RootStyleRegistry = ({ children }: { children: React.ReactNode }) => {
const [cache] = useState(() => createCache());
useServerInsertedHTML(() => {
return (
<script
dangerouslySetInnerHTML={{
__html: `</script>${extractStyle(cache)}<script>`,
}}
/>
);
});
return (
<StyleProvider cache={cache} hashPriority="high" transformers={[legacyLogicalPropertiesTransformer]}>
<App>
<MyContainer>{children}</MyContainer>
</App>
</StyleProvider>
);
};
核心就两个部分:
hashPriority="high" transformers={[legacyLogicalPropertiesTransformer]}
,只要加上这两个属性,就可以解决大部分的组件兼容问题。- 用我们自己定义的
MyContainer
组件,包裹所有的页面组件,同时用App
组件包裹。这部分则是解决弹出类组件的样式问题。
最后我们在根Layout
中,进行包裹即可完成Nextjs
中对于antd5
的降级处理:
import { RootStyleRegistry } from './RootStyleRegistry'
export default function RootLayout({ children, }: Readonly<{ children: React.ReactNode; }>) {
return (
<html lang="en">
<body>
<RootStyleRegistry>
{children}
</RootStyleRegistry>
</body>
</html>
);
}