#reactjs #next.js #media-queries #styled-components
Вопрос:
У меня есть тема:
const smartPhonePortrait = 320; const theme = { isCompact: typeof window !== 'undefined' ? window.matchMedia(`(min-width:${smartPhonePortrait}px)`).matches : false }; export default theme;
А затем я добавляю эту тему своему провайдеру
внутри _app.js:
import { ThemeProvider } from 'styled-components'; import theme from '../theme'; const App = ({ Component, pageProps, router }) =gt; { return ( lt;ThemeProvider theme={theme}gt; ... my app lt;/ThemeProvidergt; ); };
и в моем стилизованном компоненте я делаю это:
const Item = styled.div` display: flex; flex-direction: column; flex-grow: 1; flex-shrink: 0; flex-basis: ${(props) =gt; (props.theme.isCompact ? '100%' : '48%')}; `;
Это работает при первом рендеринге, но когда я изменяю размер экрана, он не обновляется. Если я на мобильном телефоне, я получаю flex-basis 100%
, но если я изменю размер экрана на рабочий стол, я не получу 48%
Как мне заставить это работать?
Комментарии:
1. Запрос
(min-width: 320px)
мультимедиа по-прежнему будет верен для размеров экрана рабочего стола. Вам нужно создать другой запрос, соответствующий размерам экрана рабочего стола.
Ответ №1:
Что вы могли бы сделать, так это сделать крюк:
import { useState, useCallback, useEffect } from 'react'; const useMediaQuery = (width) =gt; { const [targetReached, setTargetReached] = useState(false); const updateTarget = useCallback((e) =gt; { if (e.matches) { setTargetReached(true); } else { setTargetReached(false); } }, []); useEffect(() =gt; { if (typeof window !== 'undefined') { const media = window.matchMedia(`(max-width:${width}px)`); media.addListener(updateTarget); if (media.matches) { setTargetReached(true); } return () =gt; media.removeListener(updateTarget); } }, []); return targetReached; }; export default useMediaQuery;
и в вашем __app.js вы импортируете его и добавляете в свою тему:
import MediaQuery from 'hooks/useMedia'; const isCompact = MediaQuery (576); const useTheme = { ...theme, isCompact }; lt;ThemeProvider theme={useTheme}gt; ... my app lt;/ThemeProvidergt;