Реагировать Компоненты и setInterval ID - PullRequest
0 голосов
/ 15 мая 2018

Я пытаюсь написать компонент Notification React, который всплывает, а затем исчезает через 5 секунд.Может быть много уведомлений, которые накладываются друг на друга, поэтому я веду их список и отображаю их, используя map().Однако я заметил, что если я последовательно добавляю Уведомления и объявляю идентификатор setInterval внутри каждого из них, когда они отключаются, идентификатор мигрирует из одного компонента в другой.Например, предположим, что идентификатор 111 уведомления получает идентификатор 1 setInterval, а затем создается идентификатор 222 уведомления и получает идентификатор 2 setInterval. Как только уведомление 111 исчезает, внезапно идентификатор setInterval уведомления 222 теперь равен 1!Вот соответствующий код:

class Notification extends Component {

  constructor(props) {
    super(props);
    this.onClose = this.onClose.bind(this);
    this.countdownTimer = null;
    this.secondsLeft = null;
  }

  componentDidMount() {
    if(this.secondsLeft === null) {
      this.secondsLeft = 5;
      this.countdownTimer = setInterval(() => {
        this.secondsLeft = this.secondsLeft - 1;
        if (this.secondsLeft <= 0) {
          this.onClose();
        };
      }, 1000);
    };
  }

  componentWillUnmount() {
    clearInterval(this.countdownTimer);
  }

  onClose() {
    this.props.removeNotification(this.props.notification.id);
  }

// render() and other irrelevant code removed
}

Почему значение this.countdownTimer передается другому компоненту после его удаления?Может ли быть так, что список уведомлений указывает на них по позиции в списке, а не по указанным реквизитам?

РЕДАКТИРОВАТЬ: Вот соответствующие журналы, чтобы доказать это:

// Notification ID: 5a8 , timer ID: 15 , secondsLeft: 5
// Notification ID: 15a , timer ID: 16 , secondsLeft: 5
// Notification ID: 5a8 , timer ID: 15 , secondsLeft: 4
// Notification ID: 15a , timer ID: 16 , secondsLeft: 4
// Notification ID: 5a8 , timer ID: 15 , secondsLeft: 3
// Notification ID: 15a , timer ID: 16 , secondsLeft: 3
// Notification ID: 5a8 , timer ID: 15 , secondsLeft: 2
// Notification ID: 15a , timer ID: 16 , secondsLeft: 2
// Notification ID: 5a8 , timer ID: 15 , secondsLeft: 1
// Notification ID: 15a , timer ID: 15 , secondsLeft: 0

1 Ответ

0 голосов
/ 15 мая 2018

Я понял свою ошибку. Я устанавливал опору key в самом компоненте уведомлений. Я должен был установить key внутри моего map() при инициализации компонента. Например:

class NotificationsList extends Component {
    render() {
      return (
        <div className="NotificationsList">
          { this.props.notifications.map(notification => (
            <Notification
              notification={notification}
              key={notification.id}
            />
          ))}
        </div>
      );
    }
}

Первоначально я вместо этого делал это (что было неправильно):

class Notification extends Component {

  render() {
    return (
      <AnimatedAlert
        key={this.props.notification.id}
      </AnimatedAlert>
    );
  }
}
...