Реагировать на бесконечное обновление компонента - PullRequest
0 голосов
/ 28 августа 2018

У меня есть компонент React, и я буду бесконечно обновлять этот компонент всякий раз, когда я буду подключать его к избыточному каталогу и ссылаться на свойства из магазина. Если я просто ссылаюсь на одно свойство из магазина, бесконечное обновление не произойдет. Это происходит только тогда, когда я соединяю два или более, и я действительно не могу определить, почему это происходит.

Когда я добавлю shouldComponentUpdate, он фактически не остановит бесконечное обновление, он просто сильно замедлит его. Я действительно понятия не имею, что происходит.

UPDATE: Интересно, что если я просто уберу функцию componentDidUpdate, она не будет выполнять бесконечный цикл и не приведет к краху браузера.

import React, { Component } from 'react';

import { connect } from 'react-redux';

class UnreadMessages extends Component {
    constructor(props) {
        super(props);

        this.state = {
            messageReceived: false,
            unreadMessages: 0
        }

        this.unreadMessages = 0;
    }

    componentDidUpdate(prevProps, prevState) {
        if (prevProps.lastViewedMessageTime === this.props.lastViewedMessageTime) {
            this.setState({ messageReceived: true }, 
                () => {
                    setTimeout(
                        () => {
                            this.setState({ messageReceived: false });
                        }, 
                        300
                    );
                }
            );
        }

        const conOne = prevProps.messages.length !== this.props.messages.length;
        const conTwo = this.props.visible === false && window.innerWidth < 768;
        if (conTwo) {
            let index = this.props.messages.length - 1;
            const conOne = this.props.messages[index].type === 'chat.msg';
            const conTwo = this.props.messages[index].member_type === 'agent';
            if (conOne && conTwo) {
                this.setState({ 
                    unreadMessages: this.state.unreadMessages + 1 
                });
            }
        }

        if (this.props.visible === true) {
            this.setState({ unreadMessages: 0 });
        }
    }

    render () {
        let displayBadge = this.state.unreadMessages > 0 ? true : false;
        console.log('DISPLAY BAD', displayBadge)
        let pulse = this.state.messageReceived === true ? 'pulse' : '';
        console.log('PULSE', pulse)

        if (!displayBadge) {
            return null;
        }

        return (
            <span className={`msgBadge ${pulse}`}>{this.state.unreadMessages}</span>
        )
    }
}

function mapStateToProps(state) {
  return {
    lastViewedMessageTime: state.lastViewedMessageTime,
    messages: state.chats.toArray(),
    visible: state.visible
  };
}
export default connect(mapStateToProps, null)(UnreadMessages);

1 Ответ

0 голосов
/ 29 августа 2018

Как отметил @Hamms в комментариях, использование this.setState внутри componentDidUpdate, скорее всего, вызовет проблемы.

Взять первые несколько строк componentDidUpdate.

componentDidUpdate(prevProps, prevState) {
    if (prevProps.lastViewedMessageTime === this.props.lastViewedMessageTime) {
        this.setState({ messageReceived: true }, 
     ...

Если состояние или любая другая реквизит, кроме lastViewedMessageTime, изменяется и вызывает обновление, тогда реквизит lastViewedMessageTime будет таким же в текущих реквизитах, что и в prevProps.

Это приведет к изменению состояния - следовательно, к обновлению - и то же самое будет справедливо в отношении lastViewedMessageTime.

Вы уже застряли в бесконечном цикле обновления.

Вы должны посмотреть на static getDerivedStateFromProps или памятку . Это должно помочь избежать этих проблем.

...