Material UI:样式闪烁并消失

Sea*_*ysa 6 reactjs material-ui next.js

样式可能会出现 50 毫秒,然后在此 SSR 应用程序的以下代码中消失。我很好奇是什么原因造成的。

// This component is a child of index.tsx in the /pages folder
    <Button
      color="primary"
      variant="outlined"
      size="large"
    >Test Button</Button>
Run Code Online (Sandbox Code Playgroud)

样式消失后,只剩下一个普通的 HTML 按钮。

我相信 Next.js 是造成这种情况的原因。我检查了 Next.js 文件并将 next/babel 加载器添加到 .babelrc。除此之外,我只看到了其他相关的变化。这是在 /pages/_document.js 中:


MyDocument.getInitialProps = async ctx => {
  const sheets = new MuiServerStyleSheets();
  const originalRenderPage = ctx.renderPage;

  ctx.renderPage = () =>
    originalRenderPage({
      enhanceApp: App => props => sheets.collect(<App {...props} />),
    });

  const initialProps = await Document.getInitialProps(ctx);

  return {
    ...initialProps,
    // Styles fragment is rendered after the app and page rendering finish.
    styles: [...React.Children.toArray(initialProps.styles), sheets.getStyleElement()],
  };
};
Run Code Online (Sandbox Code Playgroud)

试图解决的事情

  1. 重启服务器

无需更改发行。

  1. 强制刷新 Chrome 78 (CTRL + F5)

没变。

理论

我认为存在服务器端问题。客户端和服务器应该在同一台机器上,localhost。这将解释正确的初始结果(客户端初始 UI)然后被服务器更新覆盖。

更新 1

忘了说我也更新/pages/_app.js了。这是更新的部分:

class MyApp extends App {
  componentDidMount() {
    // Remove the server-side injected CSS.
    const jssStyles = document.querySelector('#jss-server-side');
    if (jssStyles && "parentElement" in jssStyles) {
      (jssStyles.parentElement as HTMLElement).removeChild(jssStyles);
    }
  }
Run Code Online (Sandbox Code Playgroud)

R R*_*R R 8

对我来说,此错误的根本原因是在文档的服务器端呈现期间生成的类与水化后生成的样式不匹配。

解决此问题的一种方法是在 hidration 后强制重新渲染。

一种方法是更新组件上的 key 属性。

// inside your component
const [key, setKey] = React.useState(0);

React.useEffect(() => {
  setKey(1);
}, []);

return (<MyComponent key={}key />)
Run Code Online (Sandbox Code Playgroud)

我的完整_app.tsx文件:

// inside your component
const [key, setKey] = React.useState(0);

React.useEffect(() => {
  setKey(1);
}, []);

return (<MyComponent key={}key />)
Run Code Online (Sandbox Code Playgroud)


Sea*_*ysa 0

暂时通过注释掉去掉服务器的代码解决jssStyles

class MyApp extends App {
  // componentDidMount() {
  //   // Remove the server-side injected CSS.
  //   const jssStyles = document.querySelector('#jss-server-side');
  //   if (jssStyles && "parentElement" in jssStyles) {
  //     (jssStyles.parentElement as HTMLElement).removeChild(jssStyles);
  //   }
  // }
Run Code Online (Sandbox Code Playgroud)

如果有人知道为什么此代码包含在示例中,请发表评论。这一定是有原因的。https://github.com/mui-org/material-ui/blob/master/examples/nextjs/pages/_app.js