gpt4 book ai didi

javascript - React Hook - 只监听窗口 *宽度* 大小的变化

转载 作者:行者123 更新时间:2023-12-02 19:10:15 25 4
gpt4 key购买 nike

我有一个监听 window.resize 事件的钩子(Hook)。我希望只在 window.innerWidth 更改时监听和更新。我希望忽略对 window.innerHeight 的更改,因为打开软键盘时会触发此更改。问题是 mediaSize 存储在我的 Redux Store 中,导致应用程序在软键盘打开时重新渲染。

我的代码在 window.innerWidthwindow.innerHeight 更改时触发,如何更改此行为?

我的钩子(Hook)

import { useState, useEffect } from 'react';

// Hook
export const useWindowSize = () => {
const isClient = typeof window === 'object'; //Object represents browser window
function getSize() {
return {
width: isClient ? window.innerWidth : undefined
}
}

const [windowSize, setWindowSize] = useState(getSize)

useEffect(() => {
if (!isClient) { return false } //Exit if not user/browser

function handleResize() {
setWindowSize(getSize())
}
window.addEventListener('resize', handleResize) // <-- I am only interested in window.innerWidth !
return () => window.removeEventListener('resize', handleResize)
}, []) // Empty array ensures that effect is only run on mount and unmount

return windowSize
}

在我的 AppRouter.js 中实现

const AppRouter = ({ isNavOpen, mediaSize, startSetMediaSize, language, ...rest }) => {

//** Start mediaQuery */
const mediaBreakpoints = {
smallStr: styles['breakpoint-small-value'],
mediumStr: styles['breakpoint-medium-value'],
largeStr: styles['breakpoint-large-value'],
smallInt: new Number(styles['breakpoint-small-value']).valueOf(),
mediumInt: new Number(styles['breakpoint-medium-value']).valueOf(),
largeInt: new Number(styles['breakpoint-large-value']).valueOf(),
small: styles['breakpoint-small'],
medium: styles['breakpoint-medium'],
large: styles['breakpoint-large']
}

//Calculate media size
const screenWidth = useWindowSize().width
...
useEffect(() => {
if (screenWidth > mediaBreakpoints.largeInt) {
if (mediaSize !== MEDIA_LARGE) { startSetMediaSize(MEDIA_LARGE) }
} else if (screenWidth > mediaBreakpoints.mediumInt) {
if (mediaSize !== MEDIA_MEDIUM) { startSetMediaSize(MEDIA_MEDIUM) }
} else if (screenWidth > mediaBreakpoints.smallInt) {
if (mediaSize !== MEDIA_SMALL) { startSetMediaSize(MEDIA_SMALL) }
} else {
//Tiny and small are treated equally
if (mediaSize !== MEDIA_SMALL) { startSetMediaSize(MEDIA_SMALL) }
}
}, [screenWidth]) // Only run if screen width changes
}

const mapStateToProps = (state) => ({
isNavOpen : state.ui.isOpen,
mediaSize: state.ui.mediaSize, //small / medium / large
language: state.usersettings.language //se||en
})

const mapDispatchToProps = (dispatch) => ({
startSetNavigationState: (isOpen) => dispatch(setNavigationState(isOpen)),
startSetMediaSize: (mediaSize) => dispatch(setMediaSize(mediaSize))
})

//export default AppRouter
export default connect(mapStateToProps, mapDispatchToProps)(AppRouter)

我的 AppRouter 挂载点

const jsx = (
<React.StrictMode>
<Provider store={store}>
<AppRouter />
</Provider>
</React.StrictMode>
)

亲切的问候/K

最佳答案

我能想到的一个简单的解决方案是缓存最后一个innerWidth,并且仅在它发生变化时才执行调整大小逻辑。像这样的事情:

import { useState, useEffect, useRef } from 'react';

// Hook
export const useWindowSize = () => {
const isClient = typeof window === 'object'; //Object represents browser window
const lastWidth = useRef();

function getSize() {
return {
width: isClient ? window.innerWidth : undefined
}
}

const [windowSize, setWindowSize] = useState(getSize)

useEffect(() => {
if (!isClient) { return false } //Exit if not user/browser

function handleResize() {
if (window?.innerWidth !== lastWidth.current) {
const width = getSize();
lastWidth.current = width;
setWindowSize(width)
}
}
window.addEventListener('resize', handleResize) // <-- I am only interested in window.innerWidth !
return () => window.removeEventListener('resize', handleResize)
}, []) // Empty array ensures that effect is only run on mount and unmount

return windowSize
}

关于javascript - React Hook - 只监听窗口 *宽度* 大小的变化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64411993/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com