Ad

ReactJS - SetState Error When UnMounting And Mounting

- 1 answer

I am new to React so I may not understand the correct concept of thinking.

I want to do auto update data component that can me mounted and unmounted.

This is a error that I get when I unmounted and then mounted component:

Warning: setState(...): Can only update a mounted or mounting component. This usually means you called setState() on an unmounted component. This is a no-op. Please check the code for the MeasurementsDataTable component.

and here is the code:

var getDataInretval;
var listenersService = new ListenersService();
var Data = [{}];

function ListenersService(){
    var listeners = {};
    this.addListener = function(callback){
        var id;
        if(typeof callback === 'function'){
            id = Math.random().toString(36).slice(2);
            listeners[id] = callback;
        }
        return id;
    }
    this.removeListener = function( id){
        if(listeners[id]){
            delete listeners[id];
            return true;
        }
        return false;
    }
    this.notifyListeners = function(data){
        for (var id in listeners) {
            if(listeners.hasOwnProperty(id)){
                listeners[id](data);
            }
        }
    }
}


var dataSevice = new DataMeasurementService(ListenersService);

function DataMeasurementService(ListenersService){

    Data.push( new MeasurementDataForTable("header1", "th", "Phase measurements", "L1", "L2", "L3", "Total", "Others") );
    var self = this;

    //var listenersService = new ListenersService();
    this.addListener = listenersService.addListener;
    this.removeListener = listenersService.removeListener;
    this.getData = function(){
        return Data;
    }

    $.ajax({
        url: "BL/getMeasurementsData.php",
        type: "GET",
        dataType: "html",
        async: false,
        success: function(res) {
            var parseData = parseMeasurementsData( res );
            Data = createOriginData( parseData );
        },
        error: function(request, status, error) {
            alert("error: " + request.responseText);
        }
    });
    listenersService.notifyListeners(Data);
}

var ThElement = React.createClass({
   render: function(){
       return <th  width={this.props.width}>{this.props.data}</th>;
   }
});

var TdElement = React.createClass({
    render: function(){
        return <td>{this.props.data}</td>;
    }
});

var MeasurementsDataTable = React.createClass({
    getInitialState: function() {
        return {
            data: this.props.dataService.getData()
        };
    },
    componentDidMount: function() {
        getDataInretval = setInterval(function(){
            $.ajax({
                url: "BL/getMeasurementsData.php",
                type: "GET",
                dataType: "html",
                async: false,
                success: function(res) {
                    var parseData = parseMeasurementsData( res );
                    Data = createOriginData( parseData );
                },
                error: function(request, status, error) {
                    alert("error: " + request.responseText);
                }
            });

            listenersService.notifyListeners(Data);
        }, 1000);


    },
    componentWillMount: function () {
        this.props.dataService.addListener(this.updateHandler);
    },
    componentWillUnmount: function () {
        this.removeListener = listenersService.removeListener;
        clearInterval(getDataInretval);
    },
    updateHandler: function(data) {
        this.setState({
            data: data
        });
    },
    render: function() {
        return (
            <div>
                <table>
                    {
                        this.state.data.map(function(item) {
                                if( item.element == "th" ){
                                    return (
                                        <thead><tr>
                                            <ThElement width="280" data={item.description}/>
                                            <ThElement width="150" data={item.L1}/>
                                            <ThElement width="150" data={item.L2}/>
                                            <ThElement width="150" data={item.L3}/>
                                            <ThElement width="150" data={item.total}/>
                                            <ThElement width="150" data={item.others}/>
                                        </tr></thead>
                                    )
                                }
                                else{
                                        return (
                                            <tr>
                                                <TdElement data={item.description}/>
                                                <TdElement data={item.L1}/>
                                                <TdElement data={item.L2}/>
                                                <TdElement data={item.L3}/>
                                                <TdElement data={item.total}/>
                                                <TdElement data={item.others}/>
                                            </tr>
                                        )
                                    }
                        })
                    }
               </table>
            </div>
        );
    }
});
ReactDOM.render( <MeasurementsDataTable dataService={dataSevice} />, document.getElementById("tablePlaceHolder") );

Ad

Answer

You have to make sure that your component isn't still listening to an attached event-listener and trying to update itself after being unmounted.

You need to keep track of ALL event listeners while using React. If data from event listeners cause your component to update, you must attach the listener to the Lifecycle method componentWillMount() and detach all your listeners in componentWillUnmount().

Listeners can be anything which your component listens to and changes itself by setState() method. It can be data from socket, data from server, on window resize event, setInterval listener etc.

Ad
source: stackoverflow.com
Ad