pro-react-redux icon indicating copy to clipboard operation
pro-react-redux copied to clipboard

starDB, changeService Button

Open Supermann89 opened this issue 4 years ago • 0 comments

В приложение starDB при смене контекста по кнопке changeService в консоле появляется предупреждение:

index.js:1 Warning: Can't perform a React state update on an unmounted component. This is a no-op, but it indicates a memory leak in your application. To fix, cancel all subscriptions and asynchronous tasks in the componentWillUnmount method. in _temp (at with-child-function.js:6) in Unknown (at with-data.js:65)

Для того, чтоб убрать данный warning в модуле hoc-helpers/with-data.js помогает добавить локальную переменную _isMounted для отслеживания состояния компонента, и состояние обновляется только если компонент ещё смонтирован. Есть ли менее топорный вариант избежать данного предупреждения? Может нужна более гибкая реализация swapi-service?

import React, { Component } from 'react';
import Spinner from '../spinner';
import ErrorIndicator from '../error-indicator';

const withData = (View) => {
  return class extends Component {
    **_isMounted = false;**

    state = {
      data: null,
      loading: true,
      error: false
    };

    componentDidUpdate(prevProps) {
      if (this.props.getData !== prevProps.getData) {
        this.update();
      }
    }

    componentDidMount() {
      **this._isMounted = true;**
      this.update();
    }

    componentWillUnmount() {
      this._isMounted = false;
    }

    update() {
      this.setState( {
        loading: true,
        error: false
      });

      this.props.getData()
        .then((data) => {
          **if (this._isMounted) {**
            this.setState({
              data,
              loading: false
            });
          }
        })
        .catch(() => {
          this.setState({
            error: true,
            loading: false
          });
        });
    }


    render() {
      const { data, loading, error } = this.state;

      if (loading) {
        return <Spinner />;
      }

      if (error) {
        return <ErrorIndicator />;
      }

      return <View {...this.props} data={data} />;
    }
  };
};

export default withData;

Supermann89 avatar Apr 04 '20 21:04 Supermann89