Null ref после переключения маршрута в React - PullRequest
0 голосов
/ 03 июля 2019

У меня есть интересная ошибка, с которой я не могу справиться, и я надеюсь, что кто-то с лучшим знанием React, чем я, сможет мне помочь.

По сути, у меня есть компонент (карусель ползунка, например очередь Netflix), который пытается установить видимость двух элементов (кнопки ползунка навигации для навигации влево и вправо), если имеется переполнение базового устройства и / или если лежащий в основе div находится в определенной позиции. Мой метод установки видимости вызывается, когда onComponentDidMount, когда изменяется положение нижележащего элемента div и прослушивается событие изменения размера окна.

В большинстве случаев он работает, как и ожидалось, однако у меня есть крайний случай, когда я могу изменить размер окна даже после перехода на новый маршрут, и он будет работать, как и ожидалось ... НО, если я пойду по новому маршруту снова я получаю ошибку при изменении размера окна в этой точке.

Похоже, что ссылки не устанавливаются после переключения маршрутов во второй раз, потому что они возвращают ноль.

Я попытался определить, имеет ли ref значение null, но не смог правильно выполнить эту работу.

setCaretVis() {

 const el = this.tray.current;
 console.log(el);

 const parent = this.wrapper.current;
 console.log(parent);

 const posRight = this.offsetRight();
 const posLeft = el.scrollLeft;
 const left = this.caretLeft.current;
 const right = this.caretRight.current;

 const parWidth = el.parentElement.offsetWidth;


 const width = el.scrollWidth;


 if (parWidth >= width) {

   if (!left.classList.contains("invis")) {
     left.classList.add("invis");
   } else if (left.classList.contains("invis")) {

   }
   if (!right.classList.contains("invis")) {
     right.classList.add("invis");
   }
 } else if (parWidth < width) {
   if (left.classList.contains("invis") && posLeft != 0) {
     left.classList.remove("invis");
   } else if (!left.classList.contains("invis") && posLeft === 0) {
     left.classList.add("invis");
   }
   if (right.classList.contains("invis") && posRight != 0) {
     right.classList.remove("invis");
   } else if (!right.classList.contains("invis") && posRight === 0) {
     right.classList.add("invis");
   }
 }


 if (posLeft > 0) {
   left.classList.remove("invis");
  } else {
   left.classList.add("invis");
  }
 if (posRight === 0) {
  console.log("true");
  right.classList.add("invis");
 } else {
  right.classList.remove("invis");
 }
}

offsetRight() {
 const el = this.tray.current;
 //const element = this.refs.tray;

 const parent = this.wrapper.current;
 const parWidth = parent.offsetWidth;

 const width = el.scrollWidth;

 const left = el.scrollLeft;

 let sub = width - parWidth;
 let calc = Math.abs(left - sub);

 return calc;
};

// The componentDidMount method
   componentDidMount() {
   this.setCaretVis();
   window.addEventListener("resize", this.setCaretVis);
   this.setCaretVis();
}

Я бы хотел установить видимость (добавление / удаление класса CSS) при изменении размера после изменения маршрута без ошибок.

текущая ошибка: Uncaught TypeError: Невозможно прочитать свойство 'offsetWidth' со значением NULL

1 Ответ

1 голос
/ 04 июля 2019

Я подозреваю, что ваш компонент воссоздается, когда вы снова идете по новому маршруту, но старый обработчик по-прежнему вызывается обработчиком resize. Попробуйте удалить прослушиватель событий в componentWillUnmount:

componentDidMount() {
    this.setCaretVis();
    window.addEventListener("resize", this.setCaretVis);
    this.setCaretVis();
}

componentWillUnmount() {
    window.removeEventListener("resize", this.setCaretVis);
}

Когда маршрутизатор заново создает компонент, он снова подписывается на событие resize.

Из документов:

componentWillUnmount () вызывается непосредственно перед размонтированием и уничтожением компонента. Выполните любую необходимую очистку в этом методе, такую ​​как аннулирование таймеров, отмена сетевых запросов или очистка любых элементов DOM, которые были созданы в componentDidMount

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...