代码之家  ›  专栏  ›  技术社区  ›  Or Assayag

反应警告:只能更新已安装或已安装的组件

  •  1
  • Or Assayag  · 技术社区  · 6 年前

    我有两个组件,通过使用来自react router dom的路由组件在它们之间路由。其中一个组件从componentdidmount事件上的虚拟API服务器获取数据(使用AXIOS包),下面是代码:

        componentDidMount() {
        axios.get('/posts')
            .then(response => {
                const posts = response.data.slice(0, 4);
                const updatedPost = posts.map(post => {
                    return {
                        ...post,
                        author: 'Max'
                    };
                });
                this.setState({ posts: updatedPost });
            })
            .catch(error => {
                console.log(error);
            });
    }
    

    错误是,当我从一个组件重定向到另一个组件的速度太快,或者某个组件的速度不够快时,我会在控制台上收到以下警告:

    “警告:只能更新已安装或正在安装的组件。这通常意味着您在未安装的组件上调用了setState、replaceState或forceUpdate。这是不允许的。

    请检查“Posts”组件的代码。“

    我能做些什么来解决这个问题? 我试图通过以下方式来解决: setState(...): Can only update a mounted or mounting component. This usually means you called setState() on an unmounted component. This is a no-op 但我不太明白什么时候才能通过裁判以及如何通过。如果有人能举例说明这个问题是如何解决的,那就太好了。谢谢!

    2 回复  |  直到 6 年前
        1
  •  3
  •   dubes user2167877    6 年前

    setState unmounted cancel

    blog componentWillUnmount

    class ExampleComponent extends React.Component {
      state = {
        externalData: null,
      };
    
      componentDidMount() {
        this._asyncRequest = asyncLoadData().then(
          externalData => {
            this._asyncRequest = null;
            this.setState({externalData});
          }
        );
      }
    
      componentWillUnmount() {
        if (this._asyncRequest) {
          this._asyncRequest.cancel();
        }
      }
    
      render() {
        if (this.state.externalData === null) {
          // Render loading state ...
        } else {
          // Render real UI ...
        }
      }
    }
    

    supports

        2
  •  0
  •   Or Assayag    6 年前

    const CancelToken = axios.CancelToken;
    let cancel;
    
    class Posts extends Component {
    
        asyncRequest = null;
        state = {
            posts: []
        };
    
        componentDidMount() {
            this.asyncRequest = axios.get('/posts', {
                cancelToken: new CancelToken(function executor(c) {
                    // An executor function receives a cancel function as a parameter
                    cancel = c;
                })
            })
                .then(response => {
                    const posts = response.data.slice(0, 4);
                    const updatedPost = posts.map(post => {
                        return {
                            ...post,
                            author: 'Max'
                        };
                    });
                    this.setState({ posts: updatedPost });
                })
                .catch(error => {
                    console.log(error);
                });
        }
    
        componentWillUnmount() {
            if (this.asyncRequest) {
                cancel();
            }
        }
    }