Реагируйте, обнаруживайте устройство при изменении ширины или высоты страницы

#javascript #reactjs #react-hooks

Вопрос:

Мне нужна глобальная переменная, которая говорит мне, какое устройство я в настоящее время использую, моя команда хочет, чтобы у меня был мобильный, планшет, рабочий стол и мобильный ландшафт. Я понятия не имел, как это сделать, но я начал копаться в Google и обнаружил эту функцию:

 const DeviceDetector = () => {
    
      let hasTouchScreen = false;
      if ("maxTouchPoints" in navigator) {
        hasTouchScreen = navigator.maxTouchPoints > 0;
      } else if ("msMaxTouchPoints" in navigator) {
        hasTouchScreen = navigator.maxTouchPoints > 0;
      } else {
        const mQ = matchMedia("(pointer:coarse)");
        if (mQ amp;amp; mQ.media === "(pointer:coarse)") {
          hasTouchScreen = !!mQ.matches;
        } else if ("orientation" in window) {
          hasTouchScreen = true; // deprecated, but good fallback
        } else {
          // Only as a last resort, fall back to user agent sniffing
          const UA = navigator.userAgent;
          hasTouchScreen =
            /b(BlackBerry|webOS|iPhone|IEMobile)b/i.test(UA) ||
            /b(Android|Windows Phone|iPad|iPod)b/i.test(UA);
        }
      }
      if (hasTouchScreen) {
        setDeviceType("Mobile");
      } else {
        setDeviceType("Desktop");
      }
    }
 

но здесь две проблемы, во-первых: эта функция обнаруживает только мобильные и настольные устройства, но более серьезная проблема в том, что мне нужна эта функция, которая срабатывает всякий раз, когда изменяется ширина или высота страницы, что я и попытался сделать, добавив ее в этот эффект использования:

 useEffect(() =>{
      DeviceDetector();

      console.log('changing device type', deviceType);
      
    },[window.innerWidth, window.innerHeight, window.outerWidth, window.outerHeight])
 

На мгновение показалось, что он работает нормально, но при запуске он всегда отображается либо на мобильном устройстве, либо на рабочем столе, в зависимости от того, с чем вы загрузили страницу.
Я был бы рад, если бы кто-то из вас столкнулся с той же проблемой и мог бы направить меня в правильном направлении, есть ли инструмент для облегчения работы, я читал о react-device-detect, но, похоже, ему также требуется обновление страницы для обнаружения изменений устройства.
Я перепробовал кучу вещей, касающихся ландшафтного мобильного телефона, но безуспешно.

Ответ №1:

Тебе бы не помешал крюк. Ранее я использовал это для доступа к размерам экрана:

 import { useState, useEffect } from 'react';

function getWindowDimensions() {
  const { innerWidth: width, innerHeight: height } = window;
  return {
    width,
    height
  };
}

export default function useWindowDimensions() {
  const [windowDimensions, setWindowDimensions] = useState(getWindowDimensions());

  useEffect(() => {
    function handleResize() {
      setWindowDimensions(getWindowDimensions());
    }

    window.addEventListener('resize', handleResize);
    return () => window.removeEventListener('resize', handleResize);
  }, []);

  return windowDimensions;
}
 

Вы можете сопоставить размеры с устройствами, чтобы получить то, что вы ищете.

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

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

2. Ты уверен? Когда я использую этот крючок, он изменяет состояние измерения при изменении размера окна просмотра (с помощью Chrome).

3. Может быть, я неправильно использую крючок, я попытался импортировать его и присвоить ему состояние, например: const [Тип устройства, setDeviceType] = useState(useWindowDimensions()); а затем попытался использовать эффект для регистрации типа устройства каждый раз, когда тип устройства меняется, но журналы были идентичными, т. к. он не меняется, может быть, это моя ошибка, как именно вы использовали крючок ?

4. Я использую его здесь: github.com/danielsteman/spotifycluster/blob/master/… , поэтому убедитесь, что компонент сюжета всегда находится в полноэкранном режиме.

5. хм, старндж, изменение его с const [тип устройства, setDeviceType] = useState(useWindowDimensions()) на — const { ширина, высота } = useWindowDimensions (), похоже, решает проблему, большое вам спасибо!