服务器和客户端呈现的组件之间的className不一致 [英] Inconsistent classNames between server and client rendered components

查看:122
本文介绍了服务器和客户端呈现的组件之间的className不一致的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我遇到一个问题,即客户端渲染的组件类名(使用makeStyles创建的自定义类名)的格式为jss1234,但是在服务器上进行渲染时,它们的格式为makeStyles-name-1234.然后补水会引起问题.

I have an issue whereby my client rendered components class names (custom class names created with makeStyles) are of the format jss1234, however when rendering on the server they are of the format makeStyles-name-1234. Causing issues when I then hydrate.

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

I have followed the server side set up here: https://material-ui.com/guides/server-rendering/#handling-the-request pretty much to the letter.

我的客户入口点看起来像:

My client entry point looks something like:

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'.

This is only an issue in production and I have ensured that both my server and client side code have process.env.NODE_ENV === 'production'.

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

I don't mind which format my classnames are, as long as they are consistent. I have tried using the StylesProvider and creating a new generateClassName function to force one way or the other, but it just doesn't seem to work. Client is always jss and server is always makeStyles prefixed.

还有其他配置方法吗?

谢谢,我会在发现问题时使用更多信息来更新问题.

thanks, in advance, I will update the question with any more information as I find it.

更新

仔细检查后,似乎无法覆盖generateClassName函数,我传入了一个并生成了一个函数,但并不是那个被调用的函数.

On closer inspection it looks as though I cannot override the generateClassName function, I pass one in and a function is generated, but its not that one that gets called.

我有以下内容:

  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.

But the disableGlobal never takes effect, it looks as though it never actually uses this function. I must be missing some configuration, however I find the documentation about this stuff a little fragmented and it seems to suggest I wouldn't need to use StylesProvider on the server with the new API.

提前谢谢.

推荐答案

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

I had the some problem. I follow the exact tutorial in https://material-ui.com/guides/server-rendering/#handling-the-request. The development build works fine, but when running the production build on node, the server side rendering used development class names, causing a class mismatch on hydration.

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

I solved this by including the NODE_ENV enviroment variable on node bootstrap on production server.

NODE_ENV=production node server.js

这篇关于服务器和客户端呈现的组件之间的className不一致的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆