在Next.js中使用MatchMedia进行多端适配的解决方案
95
2024-06-28 18:15
5 个月前
NextJS与MatchMedia使用问题
问题分析
在我们进行应用开发的时候,往往会涉及到多端适配的开发。我们会有PC端,H5端,那在NextJs中,如何完成在不同主体项目开发的时候默认渲染哪个端的问题,首先NextJs是一个SSR框架,代码会在我们的服务器上运行,在服务器上运行是,是没有设备的device信息的。所以默认都会是false。那正常的使用react-responsive这种npm包,会一直是false,那意味着封装hooks的时候我们会封装成一个isMobile的hooks
export const useIsMobile = ()=>{
return useMediaQuery({
query:'(max-width: 768px)'
});
}
如果这个是PC端的项目,那进去则没有人问题,一进去就是默认为false,如果我们的项目是以手机端为主的话,则会一直显示为false,那则会渲染PC端的代码。
那我们改如何改造呢?我发现chakra-ui的hooks能解决问题,但是引入这个也太大了。下面我们完成自己的hooks吧。
代码展示
function listener(query: MediaQueryList, callback: MediaQueryCallback) {
try {
query.addEventListener('change', callback);
return () => query.removeEventListener('change', callback);
} catch (e) {
query.addListener(callback);
return () => query.removeListener(callback);
}
}
function getInitialValue(query: string, initialValue?: boolean) {
if (typeof initialValue === 'boolean') {
return initialValue;
}
if (typeof window !== 'undefined' && 'matchMedia' in window) {
return window.matchMedia(query).matches;
}
return false;
}
export function useMediaQuery(
query: string,
initialValue?: boolean,
) {
const [matches, setMatches] = useState(
getInitialValue(query,initialValue)
);
const queryRef = useRef<MediaQueryList>();
useEffect(() => {
if ('matchMedia' in window) {
queryRef.current = window.matchMedia(query);
setMatches(queryRef.current.matches);
return listener(queryRef.current, (event) => setMatches(event.matches));
}
return undefined;
}, [query]);
return matches;
}
解决办法
其实就是加了个默认返回值,因为用户是可以知道现在要做的是哪个为主的应用,只要加个返回值,我们就可以对这个问题简单就解决了