next.js 与nextjs和材料uiv4有关的fouc问题首先加载原始html

v8wbuo2f  于 2022-11-05  发布在  其他
关注(0)|答案(1)|浏览(109)

我最近迁移到nextjs. im使用材料v4和下一个版本10.2我尝试了官方的例子在材料ui网站,以防止加载原始html第一次通过添加_document. js文件https://github.com/mui/material-ui/tree/v4.x/examples/nextjs到目前为止,我的问题仍然存在。这是我的_document. js

import React from 'react';
import Document, { Html, Head, Main, NextScript } from 'next/document';
import { ServerStyleSheets } from '@material-ui/core/styles';
import theme from '../assets/theme';

class MyDocument extends Document {
  render() {
    return (
      <Html lang="en">
        <Head>
          <meta name="theme-color" content={theme.palette.primary.main} />
          <link
            rel="stylesheet"
            href="https://fonts.googleapis.com/css?family=Lato:300,400,500,700&display=swap"
          />
        </Head>
        <body>
          <Main />
          <NextScript />
        </body>
      </Html>
    );
  }
}

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

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

  const initialProps = await Document.getInitialProps(ctx);

  return {
    ...initialProps,

    styles: [
      ...React.Children.toArray(initialProps.styles),
      sheets.getStyleElement(),
    ],
  };
};
export default MyDocument;

这是我的_app. js

import React from 'react';
import PropTypes from 'prop-types';
import Head from 'next/head';
import { ThemeProvider } from '@material-ui/core/styles';

import theme from '../assets/theme';
import withMui from '../components/withMui';
import store from '../utils/store';
import { makeStyles } from '@material-ui/core/styles';
import { Provider } from 'react-redux';
import Ribbon from '../components/RibbonComponent';
const useStyles = makeStyles(() => ({
  '@global': {
    '*::-webkit-scrollbar': {
      width: '0.4em',
    },
    '*::-webkit-scrollbar-track': {
      '-webkit-box-shadow': 'inset 0 0 6px rgba(0,0,0,0.00)',
    },
    '*::-webkit-scrollbar-thumb': {
      backgroundColor: 'rgba(0,0,0,.1)',
    },
  },
  appWrapper: {
    width: '100%',
    height: '100%',
    display: 'flex',
    flexDirection: 'column',
  },
  appContent: { flex: 1 },
}));
function MyApp(props) {
  const { Component, pageProps } = props;

  const classes = useStyles();
  React.useEffect(() => {
    // Remove the server-side injected CSS.
    const jssStyles = document.querySelector('#jss-server-side');
    if (jssStyles) {
      jssStyles.parentElement.removeChild(jssStyles);
    }
  }, []);

  return (
    <React.Fragment>
      <Head>
        <title>Tisitano</title>
        <link
          rel="stylesheet"
          href="https://fonts.googleapis.com/css?family=Lato:300,400,500,700&display=swap"
        />
        <meta
          name="viewport"
          content="minimum-scale=1, initial-scale=1, width=device-width"
        />
        <script src="https://www.gstatic.com/firebasejs/5.5.3/firebase-app.js"></script>
        <script src="https://www.gstatic.com/firebasejs/5.5.3/firebase-firestore.js"></script>
        <script
          strategy="afterInteractive"
          dangerouslySetInnerHTML={{
            __html: `myfacebookKeyAndrelatedHtml`,
          }}
        />
      </Head>
      <ThemeProvider theme={theme}>
        <Provider store={store}>
          <Ribbon />
          <div className={classes.appWrapper}>
            <div className={classes.appContent}>
              <Component {...pageProps} />
            </div>
          </div>
        </Provider>
      </ThemeProvider>
    </React.Fragment>
  );
}

MyApp.propTypes = {
  Component: PropTypes.elementType.isRequired,
  pageProps: PropTypes.object.isRequired,
};
export default withMui(MyApp);

和我的index.js

import React from 'react';

import Home from './home';

import MainFooter from '../components/home/mainFooter';

function Index() {
  return (
    <>
      <Home /> <MainFooter />
    </>
  );
}
export default Index;

我的with Mui.js文件

import React, { Component } from 'react';

import { ThemeProvider } from '@material-ui/core/styles';
import { createTheme } from '@material-ui/core/styles';
import myTheme from '../assets/theme';

const muiTheme = myTheme;

export default function outputComponent(NextPage) {
  class outputComponent extends Component {
    constructor(props) {
      super(props);
      this.state = {
        nav: '',
      };
    }
    componentDidMount() {
      this.setState(state => {
        state.nav = navigator.userAgent;
        return state;
      });
    }
    static async getInitialProps(ctx) {
      const { req } = ctx;

      const userAgent = req ? req.headers['user-agent'] : this?.state?.nav;
      let pageProps = {};
      if (NextPage.getInitialProps) {
        pageProps = await NextPage.getInitialProps(ctx);
      }

      return {
        ...pageProps,
        userAgent,
      };
    }
    render() {
      let userAgent = this.props.userAgent;
      return (
        <ThemeProvider theme={createTheme({ userAgent, ...muiTheme })}>
          <NextPage {...this.props} />
        </ThemeProvider>
      );
    }
  }

  return outputComponent;
}

以下是我目前所做的尝试:
我试着删除withMui文件,但我仍然看到了原始的html。顺便说一句,如果没有withmui文件,我所有的风格都会崩溃。
我试着把_document.js和我的withMui文件混合在一起,让它们都在服务器端,但没有成功。
3.i还确保服务器重新启动。
4.我甚至在一个github链接上看到添加一个虚拟脚本(这并不令人信服,但我尝试了)<script>0</script>,但这也不起作用。
5.i在my_app.js中添加了获取初始化属性。
1.我试着从_app.js中删除功能区和 Package 器分区,并将它们添加到索引文件中,但没有成功。
我不能更新我的材料或下一个版本,由于依赖冲突,所以如果有人知道这些版本的任何变通办法,请帮助我。

wlsrxk51

wlsrxk511#

我也遇到过这个问题,但这样做就解决了它。将您在_document.js中编写的代码替换为以下代码-

MyDocument.getInitialProps = async (ctx) => {
// Resolution order
//
// On the server:
// 1. app.getInitialProps
// 2. page.getInitialProps
// 3. document.getInitialProps
// 4. app.render
// 5. page.render
// 6. document.render
//
// On the server with error:
// 1. document.getInitialProps
// 2. app.render
// 3. page.render
// 4. document.render
//
// On the client
// 1. app.getInitialProps
// 2. page.getInitialProps
// 3. app.render
// 4. page.render

const originalRenderPage = ctx.renderPage;

// You can consider sharing the same emotion cache between all the SSR requests to speed up performance.
// However, be aware that it can have global side effects.
const cache = createEmotionCache();
const { extractCriticalToChunks } = createEmotionServer(cache);

ctx.renderPage = () =>
    originalRenderPage({
        enhanceApp: (App) =>
            function EnhanceApp(props) {
                return <App emotionCache={cache} {...props} />;
            },
    });

const initialProps = await Document.getInitialProps(ctx);
// This is important. It prevents emotion to render invalid HTML.
// See https://github.com/mui-org/material-ui/issues/26561#issuecomment-855286153
const emotionStyles = extractCriticalToChunks(initialProps.html);
const emotionStyleTags = emotionStyles.styles.map((style) => (
    <style
        data-emotion={`${style.key} ${style.ids.join(' ')}`}
        key={style.key}
        // eslint-disable-next-line react/no-danger
        dangerouslySetInnerHTML={{ __html: style.css }}
    />
));

  return {
    ...initialProps,
    emotionStyleTags,
  };
};

在您的_app.js中添加以下内容

const clientSideEmotionCache = createEmotionCache();
const { Component, emotionCache = clientSideEmotionCache,pageProps} = props;

 return(
<CacheProvider value={emotionCache}>

// your return code of _app.js
</CacheProvider>
)
MyApp.propTypes = {
Component: PropTypes.elementType.isRequired,
emotionCache: PropTypes.object,
pageProps: PropTypes.object.isRequired,
};

有关更多信息,请访问链接-https://mui.com/material-ui/guides/server-rendering/
也可以查看此链接-FOUC when using @material-ui/core with NextJS/React

相关问题