React - setState(...)只能更新已安装或安装的组件

时间:2017-05-18 13:28:25

标签: javascript reactjs

我是React的新手,我第一次偶然发现了以下错误消息:

  

警告:setState(...)只能更新已安装或已安装   零件。这通常意味着您在已卸载时调用了setState()   零件。这是一个无操作。请检查评论的代码   成分

我正在尝试理解消息告诉我的内容,但每次重新洗牌时,我仍会在控制台中每秒重复大约50次相同的错误消息,尽管组件确实按照应有的方式呈现。以下是组件:

App.js

import React, { Component } from 'react';
import $ from 'jquery';
import Commentspar from './Components/commentspar';

class App extends Component {
    constructor(props) {
        super(props);    
        this.state = {
            commentsLoading:"loading",
            commentsPre:[],
            upToId:0,
            comments:[]
        }
    }

commentsXMLrequest = () => {

    this.setState({
        commentsLoading:"loading"
    })

       //the below ajax call goes and retrieves the data to fill my components through state
      $.ajax({  
        type: "GET",  
        dataType: "json",  
        crossDomain:true,  
        url:"http://someendpoint.com/endpoint.php",
        success: function(data){

           var parsedComments = JSON.parse(data);  
           var newComments = [/* just above here I construct an array of new objects that look something like {id:0,text:"blah blah",type:"sad"} */];

                // here I populate the commentsPre array with the new array of objects
                this.setState({
                    commentsPre:newComments,
                    commentsLoading:""
                })   

            // here I call the next function (this is the one I would like to repeat)
            this.commentsShow()

        }.bind(this)
    })     
}


commentsShow = () => {

    var newId = this.state.upToId;
    // the newArray variable below is set to select which comment to show in the commentsPre array and increments every time the commentsShow function runs
    var newArray = [this.state.commentsPre[newId]];

    this.setState({
        comments:newArray,
        upToId:this.state.upToId + 1 //incrementation here
    })

    setTimeout(function(){
        // here is where i'm trying to repeat this function every second after incrementing the upToId state but it gives me the error
        this.commentsShow()
    }.bind(this),1000)
}

 componentDidMount() {       

     //initially kick of the load data function when page is loaded
     this.commentsXMLrequest()

}

render() {      

return (
    <div className="App">
        <div className="app-content-wrap">
            <div className="app-content-wrap-inner">

            <Commentspar commentsPre={this.state.commentsPre} commentsShow={this.commentsShow} commentsLoading={this.state.commentsLoading} comments={this.state.comments} />              

            </div>
        </div>    
  </div>
);
}
}

commentspar.js

import React, {Component} from 'react';
import Comment from'./comment';

class Commentspar extends Component { 

    render() {
        return (
            <div className="comments-par">
                <div className={"comments-inner " + this.props.commentsLoading}>

                    {
                       this.props.comments.map((comment) => {
                           return (
                            <Comment commentsShow={this.props.commentsShow} commentObj={comment} key={comment.id} />
                           )   
                       })
                    }
                </div>
            </div>
            )
        }
}


export default Commentspar;

Comment.js

从'react'导入React,{Component}; 从'jquery'中导入$;

class Comment扩展了Component {

 constructor(props) {
    super(props);
    this.state = {
        text:"",
        state:""
    };
  }

componentWillMount () {
    this.setState({
        text:this.props.commentObj.text
    })

}

render () {
    return (
        <div className={"comment-outer " + this.props.commentObj.type} data-type={this.props.commentObj.type}>
            <div className={"comment-inner " + this.state.loaded}>
                <div className={"comment-type " + this.props.commentObj.type}></div>
                <div className="comment-text">
                    <p className="placeholderText">{this.state.text}</p>
                </div>    
            </div>
        </div>
        )
    }
}

export default Comment;

我的结构在哪里出错,以至于当我第二次尝试this.commentsShow()时它会给我这个错误信息,我该如何重新安排我的结构来解决这个问题?

谢谢!

1 个答案:

答案 0 :(得分:0)

您无法设置已卸载组件的状态。即使已卸载组件并尝试设置此组件的状态,也会重新调用commentsShow方法,这会导致错误。如果在AJAX调用完成之前卸载组件,则会出现同样的问题。 您必须清除超时并在卸载组件时取消AJAX clall,以确保在卸载后不会尝试设置状态:

class App extends Component {
    ...
    commentsXMLrequest = () => {

        ...
           //the below ajax call goes and retrieves the data to fill my components through state
        this.myXHR =  $.ajax({  
            type: "GET",  
            dataType: "json",  
            crossDomain:true,  
            url:"http://someendpoint.com/endpoint.php",
            success: function(data){

               var parsedComments = JSON.parse(data);  
               var newComments = [/* just above here I construct an array of new objects that look something like {id:0,text:"blah blah",type:"sad"} */];

                    // here I populate the commentsPre array with the new array of objects
                    this.setState({
                        commentsPre:newComments,
                        commentsLoading:""
                    })   

                // here I call the next function (this is the one I would like to repeat)
                this.commentsShow()

            }.bind(this)
        })     
    }
    commentsShow = () => {
        ...
        this.myTimeout = setTimeout(function(){
            // here is where i'm trying to repeat this function every second after incrementing the upToId state but it gives me the error
            this.commentsShow()
        }.bind(this),1000)
    }

    componentWillUnmount() {
        clearInterval(this.myTimeout);
        this.myXHR.abort();
    }
}