Условный setInterval и clearInterval в ReactJS + Typescript - PullRequest
0 голосов
/ 06 мая 2020

В одностраничном веб-приложении карта города отображается с использованием слоя c трафика.
В настоящее время работает переключатель режима реального времени, который, если он включен, должен обновлять слой c трафика на карте каждые 5 минут.
Когда режим прямой трансляции выключен, 5-минутный таймер должен go выключиться.

Для этого требования есть подсказки для двух вариантов из нескольких блогов и сообщений.
1. Javascript методы: setInterval и clearInterval
2. Использование веб-сокетов

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

const handleOkBtnClick = (): void => {
    let timeout;
    if(live){
          timeout = setInterval(updateFilter, 60000);
          console.log('live ON == '+ timeout); // prints number like 89 or 146
        }else{
          console.log('live Off == '+ timeout); //always prints 'undefined' 
          clearInterval(timeout);           
        }
    }
}

Это похоже на условное выполнение setInterval и clearInterval не является вариантом.
Переход к javascript разработке через десять лет, что мне не хватает?
Любые предложения по альтернативному подходу будут приняты.
Использование ReactJS v16 .11, Машинопись v3.7

Ответы [ 2 ]

1 голос
/ 06 мая 2020

Проблема здесь в том, что переменная timeout определена в handleOkBtnClick, поэтому всякий раз, когда эта функция вызывается, значение тайм-аута сбрасывается на undefined, а если live имеет значение true, для него устанавливается значение timerId

Решение здесь нужно переместить таймер в переменную класса

class TrafficLights extends React.Component {
   timeout = null
   ...
   handleOkBtnClick = (): void => {
    if(live){
          this.timeout = setInterval(updateFilter, 60000);
          console.log('live ON == '+ this.timeout); // prints number like 89 or 146
        }else{
          console.log('live Off == '+ this.timeout); 
          clearInterval(this.timeout);           
        }
     }
   }
   ...
}

Теперь похоже, что вы используете функциональный компонент, поэтому вы можете сохранить тайм-аут в useRef, если вы используете response-hooks

const TrafficLights = () =>   {
   const timeout = useRef<number | null>(null);
    ...
     const handleOkBtnClick = (): void => {
        if(live){
              timeout.current = window.setInterval(updateFilter, 60000);
              console.log('live ON == '+ timeout.current); // prints number like 89 or 146
            }else{
              console.log('live Off == '+ timeout.current); 
              clearInterval(timeout.current);           
            }
         }
       }
      ...
  }
0 голосов
/ 06 мая 2020
const [timeout, setTimeout] = useState(0);  
const handleOkBtnClick = (): void => {

    if(live){      
      setTimeout(window.setInterval(updateFilter, 60000));
      console.log('timeout == '+ timeout);
    }else{
      console.log('clearInterval == '+ timeout); 
      clearInterval(timeout);          
    }
} 

Этот код работает без каких-либо предупреждений или ошибок.
Но плюсы и минусы использования window.setInterval Vs. setInterval, если таковой имеется, следует принимать во внимание.

...