首页 > 解决方案 > 服务器和客户端呈现的组件之间的类名不一致

问题描述

我有一个问题,即我的客户端渲染的组件类名(使用 makeStyles 创建的自定义类名)是 format jss1234,但是在服务器上渲染时它们是 format makeStyles-name-1234。当我补水时会引起问题。

我已经按照此处设置的服务器端进行了操作:https : //material-ui.com/guides/server-rendering/#handling-the-request

我的客户端入口点如下所示:

const Main = () => {
  useEffect(() => {
    // clean up any server side generated styles
    const jssStyles = document.querySelector('#jss-server-side');
    if (jssStyles) {
      jssStyles.parentNode.removeChild(jssStyles);
    }
  }, []);

  return (
    <ThemeProvider theme={ theme }>
      <BrowserRouter>
        <App />
      </BrowserRouter>
    </ThemeProvider>
  );
};

ReactDOM.hydrate(<Main />, root);

这只是生产中的一个问题,我确保我的服务器端和客户端代码都有process.env.NODE_ENV === 'production'.

我不介意我的类名是哪种格式,只要它们是一致的。我尝试使用 StylesProvider 并创建一个新的 generateClassName 函数来强制使用一种或另一种方式,但它似乎不起作用。客户端总是jss,服务器总是makeStyles前缀。

还有其他我缺少的配置方法吗?

谢谢,提前,我会用我找到的更多信息更新这个问题。

更新

仔细观察,似乎我无法覆盖 generateClassName 函数,我传入一个并生成了一个函数,但它不是被调用的那个。

我有以下内容:

  const generateClassName = createGenerateClassName({ disableGlobal: true });
  const css = new ServerStyleSheets({ generateClassName });

  const markup = ReactDOMServer.renderToString(
    css.collect(
      <StylesProvider generateClassName={ generateClassName }>
        <ThemeProvider theme={ theme }>
          ...

在我的客户中:

  const generateClassName = createGenerateClassName({ disableGlobal: true });

  return (
    <StylesProvider generateClassName={ generateClassName }>
      <ThemeProvider theme={ theme }>
      ...

但是 disableGlobal 从来没有生效,它看起来好像从来没有真正使用过这个函数。我一定遗漏了一些配置,但是我发现关于这些东西的文档有点零散,这似乎表明我不需要在带有新 API 的服务器上使用 StylesProvider。

提前致谢。

标签: material-ui

解决方案


我遇到了一些问题。我遵循 https://material-ui.com/guides/server-rendering/#handling-the-request中的确切教程。开发构建工作正常,但在节点上运行生产构建时,服务器端渲染使用开发类名称,导致水合类不匹配。

我通过在生产服务器上的节点引导程序中包含 NODE_ENV 环境变量来解决这个问题。

NODE_ENV=production node server.js

推荐阅读