【问题标题】:react-top-loading-bar Warning: Can't perform a React state update on an unmounted componentreact-top-loading-bar 警告:无法在未安装的组件上执行 React 状态更新
【发布时间】:2020-08-02 18:49:20
【问题描述】:

我想为顶部有进度条的网站添加功能。并安装了依赖“react-top-loading-bar”。它有效,但出现了警告。

附:我已经查看过其他类似的主题,但对我来说没有效果

import React, {Component} from "react";
import {connect} from "react-redux";
import {auth} from "../store/actions/user";
import Loader from "../UI/Preloader/loader";
import LoadingBar from "react-top-loading-bar";


// Auth(Component, reload)

// This is an HOC component, on every route change I check if user is authenticated

// reload true means that if user is not authenticated it will be redirected to login page
// if reload is false it means user is already logged in and redirected to his dashboard
// if there is no reload user can access those pages without authentication

export default function (ComposedClass, reload) {

   class AuthenticationCheck extends Component {

      _isMounted = false;
      
      state = {
         loading: true,
         progress: 0
      };

      //// checking if user is authenticated
      componentDidMount() {
         window.scrollTo(0, 0);

         this._isMounted = true;
         
         if(this._isMounted) {
            setTimeout(() => {
               this.setState({
                  progress: 100
               })
            }, 300);
         }


         if (this.props.user.authLogin && this.props.user.authLogin.id) {
            this.setState({loading: false});
         } else {
            this.props.dispatch(auth());
         }
      }

      UNSAFE_componentWillReceiveProps(nextProps) {

         this.setState({loading: false});

         if (!nextProps.user.authLogin.isAuth) {
            if (reload) {
               this.props.history.push("/login");
            }
         } else {
            if (reload === false) {
               this.props.history.push("/profile")
            }
         }
      }

      componentWillUnmount() {
         this._isMounted = false;
      }


      render() {
         if (this.state.loading) {
            return <Loader/>
         }
         return (
             <React.Fragment>
                <LoadingBar
                    color='#45C0AE'
                    height={4}
                    progress={this.state.progress}
                    // loaderSpeed={1000}
                    onLoaderFinished={() => {}}
                />
                <ComposedClass {...this.props} user={this.props.user}/>
             </React.Fragment>
         )
      }
   }

   function mapStateToProps(state) {
      return {
         user: state.user_r
      }
   }

   return connect(mapStateToProps)(AuthenticationCheck);
}

我尝试将上述方法与 (_ismounted) 一起使用,但它对我不起作用。

如果我在进度条完成达到 100% 之前同时快速更改路线,则会出现警告。但是,如果我等待 1-2 秒直到进度条完成,然后更改路线 - 在这种情况下没有警告。

【问题讨论】:

    标签: reactjs


    【解决方案1】:

    您还必须将检查添加到UNSAFE_componentWillReceiveProps,因为它也会被调用,但组件已经消失了。

      UNSAFE_componentWillReceiveProps(nextProps) {
             if(!this._isMounted){return;}
             this.setState({loading: false});
    
             if (!nextProps.user.authLogin.isAuth) {
                if (reload) {
                   this.props.history.push("/login");
                }
             } else {
                if (reload === false) {
                   this.props.history.push("/profile")
                }
             }
          }
    
          componentWillUnmount() {
             this._isMounted = false;
          }
    

    我还建议使用函数组件来使用更新更好的方法来呈现它。还有一个理由不使用UNSAFE_componentWillReceiveProps。也可以试试componentDidUpdate

    【讨论】:

    • 非常感谢您的回复,但更新 UNSAFE_componentWillReceiveProps 并没有帮助。我认为这个问题与'react-top-loading-bar'有关,它有很多属性:loaderSpeed,waitingTime ...我尝试使用属性并更改它们,但对我不起作用
    【解决方案2】:

    看来问题出在“react-top-loading-bar”上。因此,通过从文档中更改加载栏的一些属性:https://www.npmjs.com/package/react-top-loading-bar 确实帮助了我一点,通过从其默认值减少 transitionTime、loaderSped 和 waitingTime

    <LoadingBar
         transitionTime={200} // default 300
         loaderSpeed={400}    // default 400
         waitingTime={800}    // default 1000
         progress={this.state.progress}
    />
    

    从现在开始,我看到的警告较少。如果你进一步减少 waitingTime 和 loaderSpeed -> 你的加载栏会变得太快,但警告会消失。

    【讨论】:

    • 我是库的作者,我会打开它作为一个问题,我会修复它,谢谢澄清!
    猜你喜欢
    • 1970-01-01
    • 2021-03-27
    • 2019-09-11
    • 2021-08-07
    • 2020-06-14
    • 1970-01-01
    • 2021-02-24
    • 2021-12-03
    相关资源
    最近更新 更多