React Hook - useMediaQuery
O React Hook personalizado useMediaQuery
serve para lidar com consultas de mídia e criar componentes responsivos de maneira simples e eficaz. Ele encapsula a lógica necessária para verificar o estado de uma consulta de mídia e fornece uma maneira fácil de incorporar a responsividade aos seus componentes React.
Vamos explorar a implementação do useMediaQuery
passo a passo:
1. Estado interno do Hook
const [match, setMatch] = useState(initialValue);
O estado match
armazenará se a consulta de mídia está sendo correspondida no momento.
2. Debugging com useDebugValue
useDebugValue(`Query: ${queryValue}`, (name) => {
return name + ' modificado';
});
O useDebugValue é usado para fornecer informações de depuração. Neste caso, exibimos a string da consulta de mídia.
3. Efeito para lidar com alterações na resolução
useEffect(() => {
let isMounted = true;
const matchMedia = window.matchMedia(queryValue);
const handleChange = () => {
if (!isMounted) return;
setMatch(Boolean(matchMedia.matches));
};
matchMedia.addEventListener('change', handleChange);
setMatch(!!matchMedia.matches);
return () => {
isMounted = false;
matchMedia.removeEventListener('change', handleChange);
};
}, [queryValue]);
O useEffect
é usado para:
- Inicializar o estado com o valor inicial da consulta de mídia.
- Adicionar um ouvinte de alteração para a consulta de mídia.
- Atualizar o estado quando a consulta de mídia muda.
- Remover o ouvinte quando o componente é desmontado.
4. Retorno do Hook
return match;
O Hook retorna o valor atual da correspondência da consulta de mídia.
5. Código
import { useDebugValue, useEffect, useState } from 'react';
const useMediaQuery = (queryValue, initialValue = false) => {
const [match, setMatch] = useState(initialValue);
useDebugValue(`Query: ${queryValue}`, (name) => {
return name + ' modificado';
});
useEffect(() => {
let isMounted = true;
const matchMedia = window.matchMedia(queryValue);
const handleChange = () => {
if (!isMounted) return;
setMatch(Boolean(matchMedia.matches));
};
matchMedia.addEventListener('change', handleChange);
setMatch(!!matchMedia.matches);
return () => {
isMounted = false;
matchMedia.removeEventListener('change', handleChange);
};
}, [queryValue]);
return match;
};
Exemplo de uso
O componente Home
utiliza o useMediaQuery
para determinar diferentes tamanhos de tela e ajustar o estilo com base nesses tamanhos. O fundo do componente é definido dinamicamente com base nas media queries correspondidas.
const Home = () => {
const huge = useMediaQuery('(min-width: 980px)');
const big = useMediaQuery('(max-width: 979px) and (min-width: 768px)');
const medium = useMediaQuery('(max-width: 767px) and (min-width: 321px)');
const small = useMediaQuery('(max-width: 321px)');
const background = huge ? 'green' : big ? 'red' : medium ? 'yellow' : small ? 'purple' : null;
return <div style={{ fontSize: '60px', background }}>Oi</div>;
};
Neste exemplo, as diferentes consultas de mídia são usadas para determinar quatro tamanhos distintos de tela, cada um associado a uma cor de fundo específica.
Com essa implementação do useMediaQuery
, você pode facilmente criar interfaces responsivas adaptadas a diferentes dispositivos e tamanhos de tela, mantendo um código limpo e organizado.