服务器和客户端呈现的组件之间的className不一致

时间:2019-07-24 15:37:09

标签: material-ui

我遇到一个问题,即客户端渲染的组件类名(使用makeStyles创建的自定义类名)的格式为jss1234,但是在服务器上渲染时,它们的格式为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。

提前谢谢。

2 个答案:

答案 0 :(得分:0)

事实证明,这确实是NODE_ENV的问题。

在我的情况下,我是使用webpack而不是外部节点模块(使用webpack nodeExternals)来编译客户端代码。执行此操作的命令类似于:

NODE_ENV=production webpack ... && node server.js

将这些更改为单独的npm任务或类似的内容

NODE_ENV=production webpack ... && NODE_ENV=production node server.js

这解决了问题,并且我已经能够从代码中删除StylesProvider,因为新的MUI v4 API不需要它。

感谢并继续努力。

答案 1 :(得分:0)

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

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

NODE_ENV=production node server.js