React+TypeScript+CSS Modules样式加载异常:所有组件样式均被插入求助
解决React路由切换时所有CSS Modules样式被插入的问题
嘿,我完全懂你遇到的这个困扰——明明只打开了SignIn或者ResetPassword页面,结果两个组件的样式标签都跑到DOM里去了,这确实不符合预期。咱们来一步步搞定这个问题:
为啥会这样?
你现在是直接在路由文件里import了这两个组件对吧?这就意味着不管组件有没有被渲染,Webpack在打包阶段就把它们连同对应的CSS Modules都加载进来了,所以样式会全部注入DOM。exact属性只是管路由匹配规则的,没法控制组件的加载时机。
最靠谱的解决办法:组件懒加载
React自带的React.lazy和Suspense就是干这个的——让组件只有在需要渲染的时候才加载,连带它的CSS一起,这样就不会有多余的样式标签了。
改一下路由配置就行
把原来的静态导入换成动态导入,用React.lazy包起来:
import React, { lazy, Suspense } from 'react'; import { BrowserRouter, Switch, Route } from 'react-router-dom'; // 懒加载组件,只有当路由匹配时才会加载对应的代码和CSS const SignIn = lazy(() => import('./components/SignIn/SignIn')); const ResetPassword = lazy(() => import('./components/ResetPassword/ResetPassword')); function App() { return ( <BrowserRouter> {/* Suspense用来在组件加载过程中显示占位内容,比如加载提示 */} <Suspense fallback={<div>加载中...</div>}> <Switch> {/* 顺便提一句,你原来的路径写错啦,是/sign-in不是/sing-in */} <Route path='/sign-in' component={SignIn} exact /> <Route path='/reset-password' component={ResetPassword} exact /> </Switch> </Suspense> </BrowserRouter> ); } export default App;
组件里的CSS导入不用动
你原来的组件里导入CSS Modules的方式是对的,就保持这样:
// SignIn.tsx import styles from './SignIn.module.scss'; // ResetPassword.tsx import styles from './ResetPassword.module.scss';
原理说明
React.lazy加上动态import()会让Webpack把每个懒加载的组件打包成单独的代码块。当用户访问对应的路由时,浏览器才会下载这个代码块,同时加载组件关联的CSS样式,这样DOM里就只会有当前页面的样式标签了。
额外注意点
- 别在全局文件(比如
App.tsx、index.tsx)里不小心导入了这两个组件或者它们的CSS - 如果用的是
react-router-dom v6,路由语法要改成Routes和element属性,懒加载的逻辑还是一样的:<Routes> <Route path='/sign-in' element={<SignIn />} /> <Route path='/reset-password' element={<ResetPassword />} /> </Routes>
内容的提问来源于stack exchange,提问作者Matt
相关产品推荐
相关产品推荐

