Material UI使用renderToString时sx属性失效问题求助
问题分析与解决
问题原因
MUI的sx属性样式是运行时动态生成CSS类并注入页面的。用renderToString服务端渲染组件时,只会生成HTML结构,不会触发客户端的样式注入逻辑。而直接在页面渲染<BoxExample color={"#01FF00"} />时,React会在客户端挂载组件,触发MUI的样式生成与注入,此时通过dangerouslySetInnerHTML插入的HTML里的类名就能匹配到新注入的样式,所以两个绿色盒子的样式都会生效。
解决方案
方案1:直接用React组件渲染(推荐)
放弃renderToString+dangerouslySetInnerHTML的组合,直接以组件方式渲染,完全符合React的渲染机制:
export default function BasicButtons() { return ( <> <BoxExample color={"#01FF00"} /> <BoxExample color={"#00B2FF"} /> </> ); }
方案2:将sx转换为行内样式
如果必须用HTML字符串输出,可以把sx样式转为行内样式,这样renderToString生成的HTML会直接包含样式:
function BoxExample({ color }) { const inlineStyles = { backgroundColor: color, }; return ( <div style={inlineStyles}> <p>Content</p> </div> ); } export default function BasicButtons() { const html = renderToString(<BoxExample color={"#01FF00"} />); return ( <> <div dangerouslySetInnerHTML={{ __html: html }} /> <BoxExample color={"#00B2FF"} /> </> ); }
方案3:使用MUI官方服务端渲染工具链
如果是服务端渲染场景,用MUI提供的ServerStyleSheets在服务端生成并注入样式,确保客户端拿到的HTML包含所需样式:
// 服务端代码示例 import { renderToString } from "react-dom/server"; import { ServerStyleSheets } from "@mui/material/styles"; import BoxExample from "./BoxExample"; function renderHtml() { const sheets = new ServerStyleSheets(); const html = renderToString(sheets.collect(<BoxExample color={"#01FF00"} />)); const css = sheets.toString(); return ` <html> <head> <style id="jss-server-side">${css}</style> </head> <body> <div id="root">${html}</div> </body> </html> `; }
内容的提问来源于stack exchange,提问作者pomipiwimo
相关产品推荐
相关产品推荐

