#javascript #reactjs #webpack #graphql #gatsby
#javascript #reactjs #webpack #graphql #gatsby
Вопрос:
У меня возникла некоторая проблема с window
глобальным объектом в проекте сборки в gatsby. Я использую пользовательский медиа-хук для изменения входа в систему в некоторых разрешениях. Он отлично работает при запуске проекта. Но когда я пытаюсь npm run build
построить проект, Webpack выдает ошибку: WebpackError: TypeError: window.matchMedia не является функцией
const useMedia = (query) => {
const windowGlobal = typeof window !== 'undefined' amp;amp; window
const [matches, setMatches] = useState(windowGlobal.matchMedia(query).matches)
useEffect(() => {
const media = windowGlobal.matchMedia(query)
if (media.matches !== matches) setMatches(media.matches)
const listener = () => setMatches(media.matches)
media.addEventListener('change', listener)
return () => media.removeEventListener('change', listener)
}, [matches, query])
return matches
}
const match = useMedia('(max-width: 575px)')
const changeLabel = match ? 'Cancel' : 'Add Now'
Ответ №1:
Попробуйте:
const useMedia = (query) => {
const [matches, setMatches] = useState(typeof window !=='undefined' amp;amp; window.matchMedia(query).matches);
useEffect(() => {
const media = windowGlobal.matchMedia(query)
if (media.matches !== matches) setMatches(media.matches)
const listener = () => setMatches(media.matches)
media.addEventListener('change', listener)
return () => media.removeEventListener('change', listener)
}, [matches, query])
return matches
}
const match = useMedia('(max-width: 575px)')
const changeLabel = match ? 'Cancel' : 'Add Now'
Вы фиксировали значение windowMedia
(такое же, как isBrowser
) с помощью a const
, и состояние пыталось установить значение undefined
в то время, window
когда не было установлено, вы можете упростить, установив состояние только тогда, когда window
определено.
Ответ №2:
Вы делаете это неправильно. Вы устанавливаете для const windowGlobal значение true / false, а затем используете его в useState(windowGlobal...)
, что означает, что windowGlobal — это bool, а не функция. Используйте window напрямую, как в моем примере ниже:
const windowGlobal = typeof window !== 'undefined' amp;amp; window
const [matches, setMatches] = useState(windowGlobal.matchMedia(query).matches)
Я бы пошел с созданием, если установлено окно, затем выполните код.
const useMedia = (query) => {
const [matches, setMatches] = useState(windowGlobal.matchMedia(query).matches)
const isBrowser = () => typeof window !== 'undefined' amp;amp; window;
useEffect(() => {
if (isBrowser()) {
const media = window.matchMedia(query)
if (media.matches !== matches) setMatches(media.matches)
const listener = () => setMatches(media.matches)
media.addEventListener('change', listener)
return () => media.removeEventListener('change', listener)
}
}, [matches, query])
return matches
}
const match = useMedia('(max-width: 575px)')
const changeLabel = match ? 'Cancel' : 'Add Now'
Комментарии:
1. какое решение вы можете посоветовать ?
2. @Bavarius Я обновил пример того, как я это сделаю
3. когда я запускаю с
npm run
этим все в порядке, но когда я хочу создать ту же ошибкуWebpackError: TypeError: windowGlobal.matchMedia is not a function
4. Вам нужно использовать window вместо windowGlobal, который является Bool в вашем коде. Я обновил свой пример в useEffect. Используйте только window там