We read every piece of feedback, and take your input very seriously.
To see all available qualifiers, see our documentation.
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
公司官网使用 Gatsby 开发,常见的开发模式有:
UserAgent
width > 720 ? <A /> : <B />
通篇采用Hooks方式如果不熟悉可以自行查看
由于业务情况 H5 就只有一个页面展示就使用了第三个模式,下面使用不同方式来实现
function isH5() { const inMobile = window.location.href.match(/mobile/i) !== null; if (inMobile) return false; const sUserAgent = navigator.userAgent.toLowerCase(); const bIsIpad = sUserAgent.match(/ipad/i) !== null; const bIsIphoneOs = sUserAgent.match(/iphone os/i) !== null; const bIsMidp = sUserAgent.match(/midp/i) !== null; const bIsUc7 = sUserAgent.match(/rv:1.2.3.4/i) !== null; const bIsUc = sUserAgent.match(/ucweb/i) !== null; const bIsAndroid = sUserAgent.match(/android/i) !== null; const bIsCE = sUserAgent.match(/windows ce/i) !== null; const bIsWM = sUserAgent.match(/windows mobile/i) !== null; if (bIsIpad || bIsIphoneOs || bIsMidp || bIsUc7 || bIsUc || bIsAndroid || bIsCE || bIsWM) { return true; } return false; }
const BREAK_POINT = 720; function isH5(width) { // width 为 window.innerWidth 获取的 return width < BREAK_POINT; }
Gatsby 提供了 navigate 路由跳转,使用第一种判断是否为 H5 的方法,在 index.js 入口处判断跳转不同页面:
export default () => { useEffect(() => { navigate(isH5() ? '/mobile/' : '/home/', { replace: true }); }, []); return null; }
方法2是这篇文章的重点,都使用第二种判断 H5 的方法。下面一步一步实现一个最优写法
export default () => { const width = window.innerWidth; return isH5(width) ? <H5 /> : <PC />; }
当窗口调整大小时,未重新渲染对应组件
export default () => { const [width, setWidth] = useState(window.innerWidth); const handleWindowResize = () => setWidth(window.innerWidth); useEffect(() => { window.addEventListener('resize', handleWindowResize); return () => window.removeEventListener('resize', handleWindowResize); // 销毁时移除事件,防止内存泄漏 }, []); return isH5(width) ? <H5 /> : <PC />; }
节流相关概念不做赘述,给出一个简易版 throttle:
function throttle(func, delay) { let end = 0; return function(...args) { const start = Date.now(); if (start - end > delay) { end = start; func.apply(this, args); } }; }
修改代码为:
... const handleWindowResize = throttle(() => setWidth(window.innerWidth), 300); ...
使用自定义 Hook 可以将函数组件冗余代码复用
const useViewport = () => { const [width, setWidth] = useState(window.innerWidth); const handleWindowResize = throttle(() => setWidth(window.innerWidth), 300); useEffect(() => { window.addEventListener('resize', handleWindowResize); return () => window.removeEventListener('resize', handleWindowResize); }, []); return { width }; }
将入口文件index.js代码精简为:
index.js
export default () => { const { width } = useViewport(); return isH5(width) ? <H5 /> : <PC />; }
如果项目中使用useViewport次数多会造成性能损耗,改为 Context 储存浏览器视口的宽高以及计算方法:
useViewport
export const ViewportContext = createContext({}); const ViewportProvider = ({ children }) => { const [width, setWidth] = useState(window.innerWidth); const [height, setHeight] = useState(window.innerHeight); const handleWindowResize = throttle(() => { setWidth(window.innerWidth); setWidth(window.innerHeight); }, 300); useEffect(() => { window.addEventListener('resize', handleWindowResize); return () => window.removeEventListener('resize', handleWindowResize); }, []); return ( <ViewportContext.Provider value={{ width, height }}>{children}</ViewportContext.Provider> ); };
入口文件index.js中加入ViewportProvider:
ViewportProvider
export default () => { const { width } = useViewport(); return <ViewportProvider>{isH5(width) ? <H5 /> : <PC />}</ViewportProvider> }
useViewport改为:
const useViewport = () => { const { width, height } = React.useContext(viewportContext); return { width, height }; }
在使用useViewport时都是共享 Context 内数据
React Hooks 响应式布局
The text was updated successfully, but these errors were encountered:
No branches or pull requests
Gatsby 使用自定义 Hook 跳转移动端的方法总结
公司官网使用 Gatsby 开发,常见的开发模式有:
UserAgent
信息切换站点width > 720 ? <A /> : <B />
通篇采用Hooks方式如果不熟悉可以自行查看
由于业务情况 H5 就只有一个页面展示就使用了第三个模式,下面使用不同方式来实现
判断是否H5
UserAgent
innerWidth
方法1: 使用 navigate
Gatsby 提供了 navigate 路由跳转,使用第一种判断是否为 H5 的方法,在 index.js 入口处判断跳转不同页面:
方法2: 使用自定义Hooks
方法2是这篇文章的重点,都使用第二种判断 H5 的方法。下面一步一步实现一个最优写法
1. 最简方法
当窗口调整大小时,未重新渲染对应组件
2. 加入 resize
3. 加入 throttle
节流相关概念不做赘述,给出一个简易版 throttle:
修改代码为:
4. 构建 useViewport 自定义 Hook
使用自定义 Hook 可以将函数组件冗余代码复用
将入口文件
index.js
代码精简为:5. 使用 Context 提升性能
如果项目中使用
useViewport
次数多会造成性能损耗,改为 Context 储存浏览器视口的宽高以及计算方法:入口文件
index.js
中加入ViewportProvider
:useViewport
改为:在使用
useViewport
时都是共享 Context 内数据参考文章
React Hooks 响应式布局
The text was updated successfully, but these errors were encountered: