Ошибка setState на несмонтированном компоненте при использовании данных из Firebase - PullRequest
1 голос
/ 17 мая 2019

Когда смонтирован компонент ниже, все, что связано с Firebase, работает нормально.Эта проблема возникает при обновлении данных в Firebase.Затем я перехожу на другой маршрут, поэтому демонтирую этот компонент, и возникает ошибка setState.

Warning: setState(...): Can only update a mounted or mounting component. This usually means you called setState() on an unmounted component

Я попытался отключить функции Firebase в componentWillUnmount, пока я все ещекажется, ударил с ошибкой.Любая помощь будет оценена

   constructor() {
        super();
        this.state = {
            firebaseData: {}
        };
    }
    componentDidMount() {
        const { referenceId } = this.props.episode || '';
        if (referenceId) {
            this.getFirebaseData(this.removeDissallowedChars(referenceId));
        }
    }
    componentWillReceiveProps(nextProps) {
        if (this.props.values.referenceId !== nextProps.values.referenceId) {
            this.setState({
                referenceId: nextProps.values.referenceId,
            }, this.fetchWorkflows);
        }
    }
    getFirebaseData(refId) {
        const database = firebase.database().ref(`workflows/sky/${refId}`);
        database.on('value', snapshot => {
            this.setState({ firebaseData: snapshot.val() });
        }, error =>
            console.log(error)
        );
    }
    componentWillUnmount(refId) {
        const database = firebase.database().ref(`workflows/sky/${refId}`);
        database.off();
    }
    removeDissallowedChars(badRefId) {
        /**
         * BE strip characters that Firebase doesn't allow.
         * We need to do the same. Reference id will only contain the characters listed below.
         * Change needed in FE as some of our reference id's currently contain period characters.
         **/
        return badRefId.replace(/[^A-Za-z0-9-:/]+/g, '-');
    }
    fetchWorkflows() {
        const { referenceId } = this.state;
        this.props.fetchWorkflows(referenceId);
    }

1 Ответ

2 голосов
/ 17 мая 2019

У вас может быть переменная класса, которая отслеживает, смонтирован ли ваш компонент. Это будет выглядеть так:

constructor() {
    //...
    this._mounted = false;
}

componentDidMount() {
    this._mounted = true;
    //...
}

componentWillUnmount() {
    //...
    this._mounted = false;
}

Затем в любом месте, в котором вы устанавливаете состояние после асинхронного запроса, вы можете поместить оператор if, который проверяет, истинно ли _mounted.

В вашем случае:

    getFirebaseData(refId) {
        const database = firebase.database().ref(`workflows/sky/${refId}`);
        database.on('value', snapshot => {
            // Check if component is still mounted.
            if (this._mounted) {
                this.setState({ firebaseData: snapshot.val() });
            }
        }, error =>
            console.log(error)
        );
    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...