【问题标题】:Theme customization lost when rendering to string on client在客户端上呈现为字符串时主题自定义丢失
【发布时间】:2026-01-26 07:10:01
【问题描述】:

我正在使用 material-ui-next 并自定义主题以使用我的颜色样式和自定义字体。例如。排版副标题

我现在正在尝试将组件呈现为字符串,以便在谷歌地图信息窗口中使用。默认 material-ui 主题在传递给 withStyles 的回调 styles 对象中可用,但我的自定义在 styles 回调中的 theme 参数中不可用,也未应用。呈现的字符串以其他方式正确呈现(尽管没有我预期的事件)。

更简洁地说,当正常渲染时,会应用自定义。渲染到字符串时,它们不会。

一个简单的例子是一个正确运行 withStyles 的组件,但返回 div 而不是目标组件 ala:

let output = ReactDOMServer.renderToString(component); return <div dangerouslySetInnerHTML={{__html: output}} />

任何提示如何将我的主题自定义传递到 withStyles 回调 theme 参数?

【问题讨论】:

    标签: css material-ui render-to-string jss


    【解决方案1】:

    解决方案是创建一个父组件,将目标组件呈现为 ThemeProvider 的子组件。仍然没有事件处理程序(如预期的那样),但主题自定义适用。

    解决办法如下:

    MyThemeProvider.js(组件也可以轻松地用于 SSR)

    export default function MyThemeProvider({children}) {
      const muiTheme = createMuiTheme({
        typography: {
          fontFamily: '"Bryant", "Helvetica", "Arial", sans-serif',
        },
        palette: {
          primary: customBluePalette,
        },
        // ... 
      });
      return (<MuiThemeProvider theme={muiTheme}>{ children }</MuiThemeProvider>);
    }
    

    MapInfoWindowContent.js(在这里,这只是为了将 VenueRenderer 与我们的主题提供程序包装起来)

    import MyThemeProvider from '../MyThemeProvider';
    import VenueRenderer from '../VenueRenderer';
    export default function MapInfoWindowContent({resource}) {
      return (<MyThemeProvider><VenueRenderer resource={resource} /></MyThemeProvider>);
    }
    

    VenueRenderer(样式类 - 也可以独立于 MapInfoWindowContent 使用)

    const styles = (theme) => {
        // theme.palette.primary['500'] comes from customBluePalette so the injection worked.
    }
    // ...
    export default withStyles(styles, { withTheme: true })(VenueRenderer);
    

    在其他一些需要 HTML str 的组件中

    import ReactDOMServer from 'react-dom/server'
    import MapInfoWindowContent from '../MapInfoWindowContent';
    
    let infoWindowComponent = (<MapInfoWindowContent resource={ ... }/>);
    let output = ReactDOMServer.renderToString(infoWindowComponent);
    // output will have correctly injected classNames that contain customizations
    

    【讨论】: