【问题标题】:React-JSS with material-ui and server side renderingReact-JSS 与 material-ui 和服务器端渲染
【发布时间】:2020-10-01 23:32:19
【问题描述】:

我有一个 react 应用程序和一个使用 material-ui 构建的自定义组件库。 react 应用程序本身的组件使用react-jss 进行样式设置,我想避免在应用程序本身中过多地引用 material-ui,以防我将来希望替换 material-ui。

根据我的阅读,Material-UI 似乎使用 JSS 的封装版本,因此它们应该是兼容的,但我无法同时提取我自己的样式以及来自 material-ui 的样式。我似乎能够提取其中之一...

我遵循了React-JSS Server Side Rendering guide 并且效果很好,但我想知道如何最轻松地将两者的样式结合起来,而不必在任何地方都使用@material-ui/core/styles。

这是在我的应用中注册 JssProvider 的引导组件:

export const Bootstrap: React.FC<IBootstrapProps> = ({
    sheetsRegistry,
    generateId
}) => {
    return (
        <JssProvider registry={sheetsRegistry} generateId={generateId}>
            <App />
        </JssProvider>
    )
}

export default Bootstrap

sheetsRegistry 和 generateId 属性来自直接从 express 处理程序调用的渲染函数:

const render = (props: ISSRRenderProps) => {
    const sheetsRegistry = new SheetsRegistry()
    const generateId = createGenerateId()

    const appContent = renderToString(
        <Bootstrap
            sheetsRegistry={sheetsRegistry}
            generateId={generateId}
        />
    )
    return {
        appContent,
        styles: sheetsRegistry.toString()
    }
}

这为我提供了返回的样式属性中的所有自定义样式,我又将其转储到页面而没有问题。当我尝试将其与@material-ui 结合使用时,问题就出现了。简单地从库中包含一个组件并没有给我它的样式服务器端,尽管它们确实在 FOUC 之后呈现在客户端上。

使用the server rendering guide from material-ui 并修改我的Bootstrap 组件确实为我提供了material-ui 样式,但现在我自己的样式没有被收集。这还在我的 react 应用程序中添加了对 material-ui 的单个引用,但如果需要这样做,只要子组件不必使用 material-uis 样式工具,我就可以使用它。

import { ServerStyleSheets } from "@material-ui/core/styles"

export const Bootstrap: React.FC<IBootstrapProps> = ({
    sheetsRegistry,
    generateId,
    ...rest
}) => {
    const sheets = new ServerStyleSheets()
    sheetsRegistry?.add(sheets as any)
    return sheets.collect(
        <JssProvider registry={sheetsRegistry} generateId={generateId}>
            <App {...rest} />
        </JssProvider>
    )
}

有没有办法两全其美?我很想在我的 UI 库中使用 Material-UI 组件,并在全局范围内提取所有样式用于服务器端渲染。

【问题讨论】:

    标签: reactjs material-ui jss


    【解决方案1】:

    我已经能够想出一个“解决方法”,方法是修改我的渲染函数以单独收集材质 UI 样式并将它们连接起来:

    import { ServerStyleSheets } from "@material-ui/core/styles"
    
    const render = (props: ISSRRenderProps) => {
        const sheetsRegistry = new SheetsRegistry()
        const generateId = createGenerateId()
        const muiStyles = new ServerStyleSheets()
    
        const appContent = renderToString(
            muiStyles.collect(
                <Bootstrap
                    sheetsRegistry={sheetsRegistry}
                    generateId={generateId}
                />
            )
        )
    
        return {
            appContent,
            styles: muiStyles.toString() + sheetsRegistry.toString()
        }
    }
    

    相信这是一种解决方法并且可能不是最佳解决方案的原因是我仍然必须分别处理我自己的样式和 material-ui 样式。看到他们都在幕后使用 JSS,我仍然认为应该可以在同一个 sheetsRegistry 中无缝收集两者,但目前这可行。

    【讨论】:

      猜你喜欢
      • 2018-05-18
      • 2019-02-24
      • 2016-10-12
      • 1970-01-01
      • 2020-01-27
      • 1970-01-01
      • 2016-03-26
      • 2022-06-18
      • 2020-04-22
      相关资源
      最近更新 更多