在uniswap interface中的searchBar使用了这个自定义的hook,来判断是否是mobile,
// @deprecated in favor of useScreenSize 已弃用,转到useScreenSize
import { useScreenSize } from 'hooks/useScreenSize'
export function useIsMobile(): boolean {
const isScreenSize = useScreenSize()
const isMobile = !isScreenSize['sm']
return isMobile
}
所以useScreenSize这个hook是判断的核心:
import { useEffect, useState } from 'react'
//检测代码是否在浏览器环境中运行 ssr 是 global
const isClient = typeof window !== 'undefined'
不同设备的screen 界限
export const BREAKPOINTS = {
xs: 396,
sm: 640,
md: 768,
lg: 1024,
xl: 1280,
xxl: 1536,
xxxl: 1920,
}
export const navSearchInputVisibleSize = 1100
const BREAKPOINTS_ADDITIONAL = {
...BREAKPOINTS,
navSearchInputVisible: navSearchInputVisibleSize,// uniswap自定义了一个 BREAKPOINTS 用于特定组件
}
// 使用`Object.keys(BREAKPOINTS_ADDITIONAL).reduce`遍历断点对象的键,为每个断点创建一个对应的键值对,其值表示屏幕宽度是否大于断点值。
function getScreenSize():Record<key as keyof typeof BREAKPOINTS_ADDITIONAL,boolean>{
return Object.keys(BREAKPOINTS_ADDITIONAL).reduce(
(obj,key)=>{
return Object.assign(obj,{
[key]: isClient ? window.innerWidth > BREAKPOINTS_ADDITIONAL[key as keyof typeof BREAKPOINTS_ADDITIONAL] : false
}
},
{} as Record<key as keyof typeof BREAKPOINTS_ADDITIONAL,boolean>
)
}
export function useScreenSize(){
const [screenSize,setScreenSize] = useState(getScreenSize())
useEffect(()=>{
function handleResize(){
setScreenSize(getScreenSize())
}
if(isClient){
window.addEventListener("resize",handleResize)
return () => {
window.removeEventListener('resize', handleResize)
}
}
return undefinded;
},[])
return screenSize;
}
然后在通过这个hook 来自定义一些 相关的设备的函数控制 uniswap中的使用
export function useIsTablet(): boolean {
const isScreenSize = useScreenSize()
const isTablet = !isScreenSize['lg'] && isScreenSize['sm']
return isTablet
}