You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用renderToStaticMarkup渲染Material-UI组件时样式不生效问题

Material-UI组件用renderToStaticMarkup渲染后样式失效的解决办法

在尝试将Material-UI组件集成到其他库时,使用renderToStaticMarkup渲染组件后,发现通过styled创建的自定义样式完全没有生效。相关代码如下:

import * as React from "react";
import ReactDOM from "react-dom/client";
import Button from "@mui/material/Button";
import { styled } from "@mui/material";
import { renderToStaticMarkup } from "react-dom/server";

const StyledButton = styled(Button)(() => ({
  backgroundColor: "red"
}));

ReactDOM.createRoot(document.querySelector("#root")).render(
  <React.StrictMode>
    <div
      dangerouslySetInnerHTML={{
        __html: renderToStaticMarkup(<StyledButton>Test</StyledButton>)
      }}
    />
  </React.StrictMode>
);

问题原因

renderToStaticMarkup是React的服务端渲染方法,它只会生成静态HTML结构,不会触发Material-UI客户端的样式注入逻辑。而styled生成的组件样式,依赖Material-UI的客户端样式引擎动态将CSS注入到页面中,因此直接用该方法渲染出的HTML没有对应的样式。

解决方案

方案一:客户端直接渲染组件(优先推荐)

如果你的场景是纯客户端集成,完全没必要使用renderToStaticMarkup,直接渲染组件即可,Material-UI会自动处理样式注入:

import * as React from "react";
import ReactDOM from "react-dom/client";
import Button from "@mui/material/Button";
import { styled } from "@mui/material";

const StyledButton = styled(Button)(() => ({
  backgroundColor: "red"
}));

ReactDOM.createRoot(document.querySelector("#root")).render(
  <React.StrictMode>
    <StyledButton>Test</StyledButton>
  </React.StrictMode>
);

方案二:手动收集并注入样式(需用renderToStaticMarkup时)

如果确实需要生成静态HTML字符串供其他库使用,可以通过Material-UI的样式管理器手动收集样式,再注入到页面:

import * as React from "react";
import ReactDOM from "react-dom/client";
import Button from "@mui/material/Button";
import { styled, createStyleSheetManager } from "@mui/material";
import { renderToStaticMarkup } from "react-dom/server";

const StyledButton = styled(Button)(() => ({
  backgroundColor: "red"
}));

// 创建样式集合用于收集组件样式
const styleSheets = new Set();
const styleManager = createStyleSheetManager({ sheet: styleSheets });

// 渲染组件并同步收集样式
const staticHtml = renderToStaticMarkup(
  <styleManager>
    <StyledButton>Test</StyledButton>
  </styleManager>
);

// 将收集到的样式转换为可注入的CSS字符串
const collectedCss = Array.from(styleSheets).map(sheet => sheet.css).join('');

// 渲染时同时注入样式和静态HTML
ReactDOM.createRoot(document.querySelector("#root")).render(
  <React.StrictMode>
    <style>{collectedCss}</style>
    <div dangerouslySetInnerHTML={{ __html: staticHtml }} />
  </React.StrictMode>
);

这种方式通过createStyleSheetManager捕获styled组件生成的样式,再通过<style>标签手动注入到页面,就能让静态HTML的样式正常生效。

内容的提问来源于stack exchange,提问作者TheAschr

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.23 08:27:26