Java自学者论坛

 找回密码
 立即注册

手机号码,快捷登录

恭喜Java自学者论坛(https://www.javazxz.com)已经为数万Java学习者服务超过8年了!积累会员资料超过10000G+
成为本站VIP会员,下载本站10000G+会员资源,会员资料板块,购买链接:点击进入购买VIP会员

JAVA高级面试进阶训练营视频教程

Java架构师系统进阶VIP课程

分布式高可用全栈开发微服务教程Go语言视频零基础入门到精通Java架构师3期(课件+源码)
Java开发全终端实战租房项目视频教程SpringBoot2.X入门到高级使用教程大数据培训第六期全套视频教程深度学习(CNN RNN GAN)算法原理Java亿级流量电商系统视频教程
互联网架构师视频教程年薪50万Spark2.0从入门到精通年薪50万!人工智能学习路线教程年薪50万大数据入门到精通学习路线年薪50万机器学习入门到精通教程
仿小米商城类app和小程序视频教程深度学习数据分析基础到实战最新黑马javaEE2.1就业课程从 0到JVM实战高手教程MySQL入门到精通教程
查看: 19558|回复: 0

解决React首屏加载白屏的问题

[复制链接]
  • TA的每日心情
    奋斗
    2024-4-6 11:05
  • 签到天数: 748 天

    [LV.9]以坛为家II

    2034

    主题

    2092

    帖子

    70万

    积分

    管理员

    Rank: 9Rank: 9Rank: 9

    积分
    705612
    发表于 2021-4-12 15:57:26 | 显示全部楼层 |阅读模式

    众所周知,在项目中如果在资源加载请求还未完成的时候,由于阻塞机制,会出现首页白屏的问题,产生很差的用户体验。本文以react为例,提供一个解决方法。

    解决原理:使用  onreadystatechange  去监听 readyState,在资源加载完成之前加载一个只有框架的静态页面,页面不请求数据。当数据请求完成之后再将路由切换到真实的首页。

    废话不多说,上代码:

    main.js

    import React from 'react'
    import ReactDom from 'react-dom'
    import {Provider} from 'react-redux'
    import {BrowserRouter as Router, Route} from 'react-router-dom'
    import configureStore from './store'
    import Index from './containers/Index.js'
    import FirstScreen from './containers/FirstScreen.js'

    export const store = configureStore()

    function listen () {
    if (document.readyState == 'complete') { // 资源加载完成
    ReactDom.render(
    <Provider store={store}>
    <Router>
    <Route path="/" component={Index}/>
    </Router>
    </Provider>,
    document.getElementById('root')
    )
    } else { // 资源加载中
    ReactDom.render(
    <Provider store={store}>
    <Router>
    <Route path="/" component={FirstScreen}/>
    </Router>
    </Provider>,
    document.getElementById('root')
    )
    }
    }

    document.onreadystatechange = listen


    其中Index.js就是你的真实首页,FirstScreen.js就是只有框架的静态页。

    Index.js
    import React, {Component} from 'react'
    import PropTypes from 'prop-types'
    import {connect} from 'react-redux'
    import {store} from '../main'
    import {bindActionCreators} from 'redux'
    import {getLocalTime} from '../actions/localTime'
    import LocalTime from '../components/LocalTime'
    import '../static/css/Index.css'

    class Index extends Component {
    /**
    * constructor() React组件的构造函数在挂载之前被调用。
    * 在实现React.Component子类的构造函数时,
    * 应该super(props)在任何其他语句之前调用。
    * 否则,this.props会在构造函数中定义,这可能会导致错误。
    */
    constructor (props) {
    super(props)
    this.realTime = this.realTime.bind(this)
    }

    realTime () {
    setInterval(() => {
    store.dispatch(getLocalTime())
    }, 1000)
    }

    /**
    * componentWillMount()会在组件render之前立即被调用,并且永远都只执行一次。
    * 由于这个方法始终只执行一次,所以如果在这里定义了setState方法之后,页面永远都只会在加载前更新一次。
    */
    componentWillMount () {
    }

    /**
    * componentDidMount()在组件被装载后立即被调用。
    * 在这个时候之后组件已经生成了对应的DOM结构。
    * 可以在这个方法中执行setTimeout, setInterval,接口调用等。
    */
    componentDidMount () {
    this.realTime()
    }

    /**
    * componentWillReceiveProps()在组件接收到一个新的prop时被执行。
    * 这个方法在初始化render时不会被调用。
    */
    componentWillReceiveProps () {
    }

    /**
    * 返回一个布尔值。在组件接收到新的props或者state时被执行。
    * 在初始化时或者使用forceUpdate时不被执行。
    * 如果shouldComponentUpdate返回false,
    * render()则会在下一个state change之前被完全跳过,componentWillUpdate和 componentDidUpdate也不会被执行
    */
    shouldComponentUpdate (nextProps, nextState) {
    return true
    }

    /**
    * componentWillUpdate()在组件接收到新的props或者state但还没有render时被执行。
    * 在初始化时不会被执行。
    */
    componentWillUpdate (nextProps, nextState) {
    }

    /**
    * componentDidUpdate()在组件完成更新后立即执行。
    * 在初始化时不会被执行。一般会在组件完成更新后被使用。
    * 可以用来 clearInterval。
    */
    componentDidUpdate (prevProps, prevState) {
    clearInterval(this.realTime())
    }

    /**
    * render()函数应该是纯粹的,这意味着它不会修改组件状态,
    * 每次调用时都会返回相同的结果,并且不会直接与浏览器交互
    */
    render () {
    const {localTime} = this.props
    return (
    <div className='main'>
    <LocalTime localTime={localTime} getLocalTime={getLocalTime}></LocalTime>
    </div>
    )
    }
    }

    Index.propTypes = {
    localTime: PropTypes.string,
    getLocalTime: PropTypes.func
    }

    // 将state绑定到props
    const mapStateToProps = (state, ownProps) => {
    const {localTime} = state
    return {
    localTime: localTime.localTime
    }
    }

    // 将action绑定到props上
    const mapDispatchToProps = (dispatch, ownProps) => {
    return {
    getLocalTime: bindActionCreators(getLocalTime, dispatch)
    }
    }

    // 通过react-redux提供的connect方法将我们需要的state中的数据和actions中的方法绑定到props上
    export default connect(mapStateToProps, mapDispatchToProps)(Index)

    FirstScreen.js
    import React, {Component} from 'react'
    import {connect} from 'react-redux'
    import '../static/css/FirstScreen.css'

    class FirstScreen extends Component {
    constructor (props) {
    super(props)
    }

    render () {
    return (
    <div className='firstScreen'>
    我是首屏空白页
    </div>
    )
    }
    }

    export default connect()(FirstScreen)

    示例代码托管在GitHub上:https://github.com/skillnull/TheCurrentTime
    哎...今天够累的,签到来了1...
    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    QQ|手机版|小黑屋|Java自学者论坛 ( 声明:本站文章及资料整理自互联网,用于Java自学者交流学习使用,对资料版权不负任何法律责任,若有侵权请及时联系客服屏蔽删除 )

    GMT+8, 2024-5-6 09:40 , Processed in 0.066493 second(s), 29 queries .

    Powered by Discuz! X3.4

    Copyright © 2001-2021, Tencent Cloud.

    快速回复 返回顶部 返回列表