首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >带有样式组件的Next.js 9+ FOUC (Flash或非样式内容)

带有样式组件的Next.js 9+ FOUC (Flash或非样式内容)
EN

Stack Overflow用户
提问于 2020-08-02 14:47:39
回答 2查看 3.2K关注 0票数 0

花了几天时间在这个问题上,从SA和Reddit的大多数公司那里寻找解决方案和想法,但是都没有用。

在产品和本地加载时,每个负载都会显示整个html,而不需要任何样式,然后再注入DOM。

目前,这是我的项目关键文件:

_document.js

代码语言:javascript
复制
import { ServerStyleSheet } from "styled-components";
import Document, { Main, NextScript } from "next/document";

export default class MyDocument extends Document {
  static async getInitialProps(ctx) {
    const sheet = new ServerStyleSheet();
    const originalRenderPage = ctx.renderPage;

    try {
      ctx.renderPage = () =>
        originalRenderPage({
          enhanceApp: (App) => (props) =>
            sheet.collectStyles(<App {...props} />),
        });

      const initialProps = await Document.getInitialProps(ctx);
      return {
        ...initialProps,
        styles: (
          <>
            {initialProps.styles}
            {sheet.getStyleElement()}
          </>
        ),
      };
    } finally {
      sheet.seal();
    }
  }

  render() {
    return (
      <html lang="en">
      <Head>
        <title>namesjames</title>
        <link rel="icon" href="/favicon.ico" />
        <script src="/static/chrome-fix.js" />
        <link href="/above-the-fold.css" />
      </Head>
        <body>

          <script src="/noflash.js" />
          <Main />
          <NextScript />
          <script> </script>
        </body>
      </html>
    );
  }
}

_app.js

代码语言:javascript
复制
/* eslint-disable class-methods-use-this */
import App from "next/app";
import React from "react";
import { ThemeProvider } from "styled-components";
import { ParallaxProvider } from 'react-scroll-parallax';
import Header from "../components/Header";
import theme from "../theme";
import GlobalStyles from "../GlobalStyles";
import DarkModeToggle from '../components/toggle/toggleMode';
import Footer from '../components/Footer'
import LazyLoad from 'react-lazy-load';
import Router from 'next/router';
import styled from 'styled-components'
// import '../style.css'


const Loaded = styled.div`
  opacity: ${(props) => props.loaded ? "1" : "0"};
`

export default class MyApp extends App {
  state = { isLoading: false, loaded: false }

  componentDidMount() {
    // Logging to prove _app.js only mounts once,
    // but initializing router events here will also accomplishes
    // goal of setting state on route change
    console.log('MOUNT');
    this.setState({loaded: true})



    Router.events.on('routeChangeStart', () => {
      this.setState({ isLoading: true });
      console.log('loading is true, routechangeStart')
    });

    Router.events.on('routeChangeComplete', () => {
      this.setState({ isLoading: false });
      console.log('loading is false, routeChangeComplete')
    });

    Router.events.on('routeChangeError', () => {
      this.setState({ isLoading: false });
      console.log('loading is false, routeChangeError')
    });
  }
  render(): JSX.Element {
    const { isLoading } = this.state;
    const { Component, pageProps, router, loaded } = this.props;
    return (
      <Loaded loaded={this.state.loaded}>
        <ThemeProvider theme={theme}>
          <GlobalStyles />
          <ParallaxProvider>
          <Header />
           {isLoading && 'STRING OR LOADING COMPONENT HERE...'}
          <Component {...pageProps} key={router.route} />
          <LazyLoad offsetVertical={500}>
            <Footer />
          </LazyLoad>
          </ParallaxProvider>
          <DarkModeToggle />
        </ThemeProvider>
      </Loaded>
    );
  }
}

index.js

代码语言:javascript
复制
import { color } from "styled-system";
import { OffWhite } from "../util/tokens";
import Hero from "../components/Hero";
import Banner from  '../components/Banner'
import TitleText from '../components/TitleText'
import HomeTitleCopyScene from '../components/HomeTitleCopyScene'
import TwoCards from '../components/TwoCards'
import LazyLoad from 'react-lazy-load';

function Home(): JSX.Element {
  return (
    <div className="container">
      <Banner />
      <HomeTitleCopyScene />
      <LazyLoad offsetVertical={1000}>
        <TwoCards />
      </LazyLoad>
    </div>
  );
}

export default Home;

正如一些人可能看到的那样,我尝试过多种实现,只是对目前阶段可能出现的情况感到有点困惑。

感谢任何帮助,我可以根据要求提供更多的信息。非常感谢

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2020-08-04 09:58:39

我找到了两种解决办法-->

  1. 是硬样式不透明度:0进入JSX,然后在DOM中注入样式时,应用不透明度:1!重要到显示的任何组件上.

<section className="cards-block" style={{opacity:0}}>

代码语言:javascript
复制
// import Head from "next/head"; --> incorrect
import { ServerStyleSheet } from "styled-components";
import Document, { Head, Main, NextScript } from "next/document"; 

因此,->是一个没有FOUC的正确呈现和注入元素。

希望这对外面的人有帮助

票数 1
EN

Stack Overflow用户

发布于 2020-08-14 11:59:22

我为我的小投资组合项目找到了一个解决办法:

只是将这个内联css包含到我的自定义<head>_document.js中。

代码语言:javascript
复制
{<style dangerouslySetInnerHTML={{__html: `

    html {background: #333}
    body #__next div {visibility: hidden}
    body.loaded #__next div {visibility: visible}

`}}></style>}

_app.js中将“加载”类添加到主体中

代码语言:javascript
复制
if (process.browser) {
    document.body.classList.add("loaded")
}

我很确定,如果这是一个好的解决方案,任何建议都会很感激:)

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/63217373

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档