Как определить, действительно ли просматривается приложение React

#reactjs

#reactjs

Вопрос:

Итак, я создал приложение, которое отображает данные в режиме реального времени, получая их с устройств. Однако я хочу, чтобы мой сервер не получал данные, когда никто не просматривает приложение. Поэтому, по сути, мне нужен какой-то способ определить, просматривается ли приложение в данный момент, независимо от того, является ли оно настольным или мобильным, это включает вкладку в фокусе, где открыто приложение, и это то, что пользователь просматривает в данный момент, и поверх браузера ничего нет, поэтому браузер открывается направильная вкладка, но поверх нее у пользователя есть Explorer, который делает что-то совершенно другое, это для моего случая должно быть false и для мобильных устройств то же самое, в том числе, если устройство заблокировано (экран выключен).

Причина попытки сделать это — уменьшить нагрузку на устройства, чтобы данные запрашивались только тогда, когда есть кто-то, кто их просматривает.

Из того, что я исследовал, я узнал о focus blur событиях and , но я не смог заставить его работать, и я даже не знаю, правильный ли это подход, но то, что я попробовал, это:

Добавление прослушивателей событий в окно в компоненте приложения:

 function App() {
  useEffect(() => {
    window.addEventListener("focus", () => { console.log("viewed")});
    window.addEventListener("blur", () => { console.log("hidden")});
  })
}
  

Добавление их в качестве реквизитов в компонент приложения внутри index.js:

 <App onFocus={() => {console.log("viewed")}} onBlur={() => {console.log("hidden")}}/>
  

Ни то, ни другое не имело никакого эффекта, я не получил ни одного из выходных данных консоли.

Это вообще правильный подход?

Ответ №1:

Я бы добавил к приложению сокет-соединение. Тогда сервер сможет узнать, подключено ли по крайней мере X человек, и действовать соответствующим образом.

Комментарии:

1. У меня уже есть сокет-соединение с приложением, но это не позволяет выполнить работу. Он может определять только, подключен ли кто-либо или отключен. Переключение на другую вкладку не отключает пользователя, поэтому оно не сработает

2. Да, это может сработать. У вас может быть эффект использования, который приведет к отключению сокета, если пользователь перейдет на другую вкладку с document.hasFocus() .

Ответ №2:

Я бы посоветовал вам попробовать сокет для тестирования такого соединения, но поскольку вы также хотите уменьшить нагрузку на пользователя, лучше проверить, сфокусирован ли пользователь в браузере.

Для достижения этой цели я не буду добавлять этот код внутри компонента React из-за природы React, поскольку все его компоненты отображаются внутри <div id="root"></div> , другие части html-страницы по-прежнему не будут затронуты этим механизмом. Итак, что вы, вероятно, хотите сделать, это добавить код в index.html и использовать window.userFocused для передачи значения в React из индекса


Редактировать: добавлен сценарий фокусировки / размытия

 <script>
    window.addEventListener("focus", function(event) 
    { 
        console.log("window is focused");
        window.userFocused = true;
    }, false);

    window.addEventListener("blur", function(event) 
    { 
        console.log("window is blurred");
        window.userFocused = false;
    }, false);
</script>
  

Комментарии:

1. Я не могу найти никакой информации о window.userFocused

2. извините, это просто имя переменной, которое я только что придумал, вы можете сохранить, если пользователь сфокусируется на этой переменной и передаст ее в React

3. Хорошо, но давайте вернемся к тому, как мне определить, просматривается ли окно или нет в первую очередь?

4. Я добавил скрипт для фокусировки / размытия и протестировал его с помощью консоли разработчика. Вы также можете попробовать вручную добавить его в браузер и сначала посмотреть, работает ли оно для вас

Ответ №3:

В итоге я решил его практически с тем же кодом, что и изначально, с несколькими небольшими изменениями, я все еще использовал useEffect хук:

  const onFocusFunction = () => {
    // do whatever when focus is gained
  };

 const onBlurFunction = () => {
   // do whatever when focus is lost
 };

 useEffect(() => {
   onFocusFunction();

   window.addEventListener("focus", onFocusFunction);
   window.addEventListener("blur", onBlurFunction);

   return () => {
     onBlurFunction();

     window.removeEventListener("focus", onFocusFunction);
     window.removeEventListener("blur", onBlurFunction);
   };
 }, []);
  

Ответ №4:

Лучший способ — использовать document .

  document.onvisibilitychange = () => {
   console.log(document.hidden)
 }