#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)
}