Material-UI@v5如何配合Emotion使用组件的classes API?
Material-UI v5 搭配 Emotion 使用 classes API 及 RTL 适配解决方案
问题1:无需混用两个Emotion包的实现方案
你当前同时引入@emotion/react和@emotion/css的写法是冗余的,可直接用以下两种更合理的方案实现:
- 方案1:使用MUI官方封装的
makeStylesAPI,它内部已经基于Emotion实现了类名生成逻辑,返回的类名天然为字符串,完全适配classes API的类型要求:
import { makeStyles } from '@mui/styles'; import Button from '@mui/material/Button'; const useStyles = makeStyles()({ root: { margin: '16px' } }); function MyComponent() { const classes = useStyles(); return <Button classes={{ root: classes.root }}>Click me!</Button> }
- 方案2:如果要保留
@emotion/react的css写法,不需要额外引入@emotion/css,只需基于全局Emotion缓存拼接得到字符串类名即可:
import { css, useCache } from '@emotion/react'; import Button from '@mui/material/Button'; function MyComponent() { const emotionCache = useCache(); const rootClass = `${emotionCache.key}-${css({ margin: '16px' }).name}`; return <Button classes={{ root: rootClass }}>Click me!</Button> }
问题2:@emotion/css 生成样式无法RTL转换的解决方法
该问题的根本原因是@emotion/css默认使用独立的全局样式缓存实例,没有挂载你配置的stylis-plugin-rtl插件,所以生成的样式不会被转换,对应两种解决路径:
- 路径1:彻底弃用
@emotion/css,使用问题1给出的两种方案生成类名,所有样式都走@emotion/react的全局缓存,自动继承已配置的RTL插件逻辑,无需额外调整。 - 路径2:如果必须保留
@emotion/css的使用,手动给它注入带RTL插件的共用缓存即可:
// 全局配置文件中初始化共用缓存 import createCache from '@emotion/cache'; import rtlPlugin from 'stylis-plugin-rtl'; import { prefixer } from 'stylis'; import { CacheProvider } from '@emotion/react'; import { injectCache } from '@emotion/css'; const sharedCache = createCache({ key: 'mui-rtl', stylisPlugins: [prefixer, rtlPlugin], }); // 给@emotion/css注入共用缓存 injectCache(sharedCache); function App() { // 根组件挂载共用缓存,@emotion/react也使用同一份配置 return <CacheProvider value={sharedCache}>{/* 应用内容 */}</CacheProvider> }
内容的提问来源于stack exchange,提问作者Ali.Grn
相关产品推荐
相关产品推荐

