У меня есть компонент, который должен отслеживать изменение размера окна и соответствующим образом скрывать / отображать боковую панель. Я решил создать для этой цели специальный перехватчик, и, похоже, он не работает должным образом.
Основная проблема в том, что значение mainSidebar
всегда постоянно и обновление не читается должным образом.
Это сам хук:
export function useResizeListener(cb: (this: Window, e: UIEvent) => any) {
const [size, setSize] = React.useState({ width: window.outerWidth, height: window.outerHeight })
React.useEffect(() => {
function _wrapped(this: Window, e: UIEvent): any {
console.debug('setting size and calling callback', { width: this.outerWidth, height: this.outerHeight })
setSize({ width: this.outerWidth, height: this.outerHeight })
cb.call(this, e)
}
window.addEventListener('resize', _wrapped)
return () => window.removeEventListener('resize', _wrapped)
}, [size.width, size.height])
}
И это компонент, который его использует:
const shouldHaveSidebar = () => document.body.clientWidth >= ScreenSizes.Tablet
const HomePage: React.FunctionComponent<IProps> = (props) => {
const [mainSidebar, toggleMainSidebar] = React.useState(shouldHaveSidebar())
useResizeListener(() => {
console.debug('device width vs tablet width:', document.body.clientWidth, '>=', ScreenSizes.Tablet)
console.debug('shouldHaveSidebar vs mainSidebar', shouldHaveSidebar(), '!==', mainSidebar)
if (shouldHaveSidebar() !== mainSidebar) {
console.debug('setting to', shouldHaveSidebar())
toggleMainSidebar(shouldHaveSidebar())
}
})
return ...
}
При переключении размера области просмотра на устройстве Chrome dev инспектора режимы, я получаю этот вывод в консоли. Примечание. Я начал с настольного компьютера, а затем перешел на мобильный L.
setting size and calling callback {width: 1680, height: 1027}
device width vs tablet width: 1146 >= 800
shouldHaveSidebar vs mainSidebar true !== false
setting to true
setting size and calling callback {width: 425, height: 779}
device width vs tablet width: 425 >= 800
shouldHaveSidebar vs mainSidebar false !== false // <--- should be: false !== true
- Я попытался переместить функцию
_wrapper
между внешним и внутренним useEffect
крючком - Я попытался обернуть обратный вызов в setTimeout / setImmediate
- Я попытался обернуть состояние get (mainSidebar bool) функцией для его извлечения, которая определена в компоненте и вне вызова ловушки
Ни то, ни другое из них сработало.
Что я делаю не так?