首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在React.js中解决FOUC问题

如何在React.js中解决FOUC问题
EN

Stack Overflow用户
提问于 2018-06-05 07:09:55
回答 1查看 5.1K关注 0票数 1

我已经建立了react.js网站的创建-反应-应用程序。但是在生产模式中,存在FOUC,因为样式是在html呈现后加载的。

有什么办法解决这个问题吗?我一直在搜索谷歌的答案,但还没有找到合适的答案。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-06-06 19:01:48

FOUC

FOUC --所谓的非样式内容的Flash可能和许多解决这个问题的尝试一样有问题。

恰到好处

让我们考虑以下路由配置(反应路由器):

代码语言:javascript
复制
...
<PageLayout>
  <Switch>
    <Route exact path='/' component={Home} />
    <Route exact path='/example' component={Example} />
  <Switch>
</PageLayout>
...

其中PageLayout是一个简单的特制,包含带有page-layout类的div包装器并返回其子类。

现在,让我们关注基于路由的组件呈现。通常,您会使用作为component支柱的React Compoment。但是在我们的例子中,我们需要动态地获得它,以应用帮助我们避免FOUC的特性。所以我们的代码将如下所示:

代码语言:javascript
复制
import asyncRoute from './asyncRoute'

const Home = asyncRoute(() => import('./Home'))
const Example = asyncRoute(() => import('./Example'))

...

<PageLayout>
  <Switch>
    <Route exact path='/' component={Home} />
    <Route exact path='/example' component={Example} />
  <Switch>
</PageLayout>

...

为了澄清这一点,我们还将展示asyncRoute.js模块的外观:

代码语言:javascript
复制
import React, { Component } from 'react'
import PropTypes from 'prop-types'

import Loader from 'components/Loader'

class AsyncImport extends Component {
  static propTypes = {
    load: PropTypes.func.isRequired,
    children: PropTypes.node.isRequired
  }

  state = {
    component: null
  }

  toggleFoucClass () {
    const root = document.getElementById('react-app')
    if (root.hasClass('fouc')) {
      root.removeClass('fouc')
    } else {
      root.addClass('fouc')
    }
  }

  componentWillMount () {
    this.toggleFoucClass()
  }

  componentDidMount () {
    this.props.load()
      .then((component) => {
        setTimeout(() => this.toggleFoucClass(), 0)
        this.setState(() => ({
          component: component.default
        }))
      })
  }

  render () {
    return this.props.children(this.state.component)
  }
}

const asyncRoute = (importFunc) =>
  (props) => (
    <AsyncImport load={importFunc}>
      {(Component) => {
        return Component === null
          ? <Loader loading />
          : <Component {...props} />
      }}
    </AsyncImport>
  )

export default asyncRoute

hasClassaddClassremoveClass是对DOM类属性进行操作的多边形填充。 Loader是一个自定义组件,它显示自旋器。

为什么是setTimeout

仅仅因为我们需要在第二个滴答中移除fouc类。否则,它将在与呈现组件相同的情况下发生。这样就没用了。

正如您在AsyncImport组件中所看到的,我们通过添加fouc类来修改根容器。因此,为了清晰起见,HTML:

代码语言:javascript
复制
<html lang="en">
<head></head>
<body>
  <div id="react-app"></div>
</body>
</html>

另一个谜团是:

代码语言:javascript
复制
#react-app.fouc
    .page-layout *
        visibility: hidden

在导入特定组件(即:HomeExample)时应用sass。

为什么不display: none

因为我们希望所有依赖父级宽度、高度或任何其他css规则的组件都能正确地呈现出来。

它是如何工作的?

主要假设是隐藏所有元素,直到compoment准备向我们显示呈现的内容。首先,它激发asyncRoute函数,该函数向我们显示Loader,直到Component挂载和呈现。同时,在AsyncImport中,我们通过在react根DOM元素上使用类fouc来切换内容的可见性。当所有东西加载时,是时候显示所有内容了,所以我们删除这个类。

希望这能帮上忙!

感谢

这个文章,这个动态导入的概念是从反应可加载中提取的(我认为)。

来源

https://turkus.github.io/2018/06/06/fouc-react/

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

https://stackoverflow.com/questions/50694118

复制
相关文章

相似问题

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