Next.js 14集成Fluent UI出现className服务端客户端不匹配问题求助
服务端渲染与客户端渲染className不匹配问题(Fluent UI + Next.js 14)
遇到服务端渲染与客户端渲染的className不匹配问题,查阅相关话题后未找到适配自身场景的解决方案。使用Microsoft Fluent UI组件库,多个组件均出现该错误。
环境版本
- nextjs: 14.0.4
- react: 18
- fluentui/react: 8.113.1
layout.tsx代码
import Navbar from "./components/Navbar" import NavbarAndUser from "./components/NavbarAndUser"; import UserPanel from "./components/UserPanel" import TestSideBar from "./components/TestSideBar" import './globals.css' import { initializeIcons } from '@fluentui/react/lib/Icons'; initializeIcons(); export const metadata = { title: 'Next.js', description: 'Generated by Next.js', } export default function RootLayout({ children, }: { children: React.ReactNode }) { return ( <html lang="en"> <body> <div className="page-container"> <div className='navbar'> <NavbarAndUser /> </div> <div className='sidebar'> <TestSideBar /> </div> </div> {children} </body> </html> ) }
侧边栏组件代码(TestSideBar.tsx)
"use client"; import React, { useState } from 'react'; import { Nav, INavLinkGroup, IconButton,Stack, IStackStyles, INavStyles,IStyle, IButtonStyles, Text, ITextStyles} from '@fluentui/react'; import { useRouter } from 'next/navigation' import { initializeIcons } from '@fluentui/react/lib/Icons'; initializeIcons(); const SidebarWithButton: React.FunctionComponent = () => { const [isOpen, setIsOpen] = useState(false); const router = useRouter() function _onRenderGroupHeader(group: INavLinkGroup): JSX.Element { return ( <Text variant='xLarge' styles={isOpen ? navLinkOpenHeaderStyles : navLinkCloseHeaderStyles} >{group.name}</Text> ); } const toggleSidebar = () => { setIsOpen(!isOpen); }; const onClick = (e:any,item:any) => { e.preventDefault(); router.push(item.url); }; return ( <Stack styles={isOpen ? openNavStackStyles : closedNavStackStyles}> <Stack horizontalAlign='start' styles={{root:{borderBottom:'1px solid #d8d8d8'}}}> <Stack.Item> <IconButton iconProps={{ iconName: 'GlobalNavButton' }} styles={navButtonStyles} onClick={toggleSidebar} /> </Stack.Item> </Stack> <Stack.Item> <Nav onRenderGroupHeader={_onRenderGroupHeader} onLinkClick={onClick} groups={navLinkGroups} isOnTop={false} styles={navStyles} /> </Stack.Item> </Stack> ); }; const navbarIconStyles = { color: 'black', padding:'0 0.5rem' }; const navLinkGroups: INavLinkGroup[] = [ { name: 'Redovisning', links: [ { name: 'Aviseringlistor', url: '/', key: 'key1', iconProps: { iconName: 'WaitlistConfirm', style: navbarIconStyles }, }, { name: 'Filer', url: '/Filer', key: 'key2', iconProps: { iconName: 'DocumentManagement', style: navbarIconStyles }, }, ], }, { name:'Administration', links:[ { name: 'Byta lösenord', url: '/ChangePassword', key: 'key3', iconProps: { iconName: 'LockSolid', style: navbarIconStyles }, }, { name: 'Logga ut', url: '/2', key: 'key4', iconProps: { iconName: 'SignOut', style: navbarIconStyles }, }, ] } ]; const closedNavStackStyles: Partial<IStackStyles> = { root: { position: 'relative', height: '100%', width: '40px!important', overflow: 'hidden', overflowX: 'hidden', backgroundColor:'#EFEFEF', borderRight:'1px solid #D8D8D8', }, }; const openNavStackStyles: Partial<IStackStyles> = { root: { height: '100%', width: 200, overflow: 'hidden', position: 'relative', backgroundColor:'#EFEFEF', borderRight:'1px solid #D8D8D8', }, }; const navLinkOpenHeaderStyles : Partial<ITextStyles> = { root:{ padding:'0rem 1rem', fontWeight:'bold', color:'black', width:'100%', } }; const navLinkCloseHeaderStyles : Partial<ITextStyles> = { root:{ display:'none', } }; const navButtonStyles: Partial<IButtonStyles> = { root:{ width:'100%', color:'black', paddingLeft: '0.6rem', }, rootHovered:{ backgroundColor:'white!important', boxShadow: '0 4px 8px 0 rgba(0, 0, 0, 0.2)', color:'black!important', }, }; const navLinkStyles: Partial<IStyle> = { link: { selectors: { '&:hover, &:focus': { color: 'black', backgroundColor:'white!important', boxShadow: '0 4px 8px 0 rgba(0, 0, 0, 0.2)', }, }, }, }; const navStyles: Partial<INavStyles> = { root:{ marginTop:'2rem', }, link: { navLinkStyles, }, groupContent:{ marginBottom:'0rem', }, }; export default SidebarWithButton;
next.config.js代码
/** @type {import('next').NextConfig} */ const nextConfig = { reactStrictMode: false, compiler: { // Enables the styled-components SWC transform styledComponents: { displayName: false, } } } module.exports = nextConfig
恳请帮忙解决该问题。
内容的提问来源于stack exchange,提问作者Ali Kocak
相关产品推荐
相关产品推荐

