![](/img/trans.png)
[英]detecting browser window resize on mobile when switching from portrait to landscape and vice versa
[英]How to set a variable to false when ipad orientation is changed from landscape to portrait and vice versa using javascript and react?
当 iPad 方向从横向更改为纵向以及使用 react 和 javascript 从纵向更改为横向时,我想将一个变量设置为 false。
我有两个状态变量 isPopupOpen,isClicked 最初设置为 false。 单击按钮时,这些设置为 true。 当用户点击 Popup 之外的任何地方时,这些状态 isPopupOpen 和 isClicked 被设置为 false。
下面是我的代码,它工作正常。
function Parent({setIsPopupOpen, isPopupOpen}: Props) {
const {isClicked, setIsClicked} = React.useState(false);
const handleButtonClick = () => {
setIsPopupOpen(!isPopupOpen);
setIsClicked(!isClicked);
}
return () {
<button onClick={handleButtonClick}>click me </button>
<Popup>
<Overlay onClick={() => {
setIsPopupOpen(false);
setIsClicked(false);
}/>
</Popup>
}
};
现在的问题是,当用户在横向模式下使用 iPad 时,单击弹出窗口打开的按钮,现在没有关闭弹出窗口切换到纵向模式,弹出窗口会自行关闭。 现在,当用户单击按钮时,弹出窗口不会出现。
我认为这里的问题是,当用户切换到纵向模式时,弹出窗口会自行关闭并且 isClicked 状态值设置为 false。 但 isPopupOpen 状态值仍然为真。
我认为由于 isPopupOpen 是从其他组件传递的,因此在切换到不同模式时,它的值不会自动设置为 false。 而 isClicked 状态值设置为 false。
我怎么解决这个问题? 当用户切换模式时,如何将 isPopupOpen 也设置为 false。 React.useEffect 是否以某种方式用于这种情况。
有人可以帮我解决这个问题吗? 谢谢。
编辑:
根据提供的答案,我尝试过这样的事情
const onOrientationChange = React.useCallback(() => {
setIsPopupOpen(false);
}, [setIsPopupOpen]);
React.useEffect(() => {
window.addEventListener('orientationchange', onOrientationChange);
return () => {
window.removeEventListener('orientationchange', onOrientationChange);
};
}, [onOrientationChange]);
但这仍然没有显示弹出窗口。
您可以监听orientationchange
事件。 与所有发生在 React 域之外的事件的事件处理程序一样,您可以在没有依赖关系的useEffect
钩子回调useEffect
其连接一次,并在获得卸载回调时断开它:
useEffect(
() => {
// Component is being mounted, add listener
function onOrientationChange(event) {
// Or if you just want to set the flag false:
setIsPopupOpen(false);
}
window.addEventListener("orientationchange", onOrientationChange);
return () => {
// Component is being unmounted, remove listener
window.removeEventListener("orientationchange", onOrientationChange);
};
},
[] // <== No deps = only on mount
);
如果您有多个 linting 解决方案中的任何一个,他们可能会抱怨您没有将setIsPopupOpen
作为该useEffect
调用中的依赖项useEffect
。 不这样做应该是安全的,因为状态设置器应该是稳定的(在组件的生命周期内不会发生变化)。 来自useState
是。 由于您是通过 props 接收的,您需要确保该 setter 确实稳定(例如,确保它来自使用您的组件的组件中的useState
)。
如果您只是将它添加到依赖项数组中,并且它会定期更改,那么您将收到虚假调用,说方向已更改。 如果您无法获得该保证,则可以处理该问题,但需要做更多工作:
function Parent({setIsPopupOpen, isPopupOpen}: Props) {
const {isClicked, setIsClicked} = React.useState(false);
const [angle, setAngle] = React.useState(window.orientation);
const handleButtonClick = () => {
setIsPopupOpen(!isPopupOpen);
setIsClicked(!isClicked);
};
React.useEffect(
() => {
// Component is being mounted, add listener
function onOrientationChange(event) {
const newAngle = window.orientation;
if (newAngle !== angle) {
setAngle(newAngle);
setIsPopupOpen(false);
}
}
window.addEventListener("orientationchange", onOrientationChange);
return () => {
// Component is being unmounted, remove listener
window.removeEventListener("orientationchange", onOrientationChange);
};
},
[setIsPopupOpen, angle]
);
return () {
<button onClick={handleButtonClick}>click me </button>
<Popup>
<Overlay onClick={() => {
setIsPopupOpen(false);
setIsClicked(false);
}/>
</Popup>
}
};
请注意, window.orientation
属性被MDN 描述为“不再推荐”,并且事件和属性都由兼容性规范描述。 但是,直到或除非 Sensors API 出现,我无法想象移动浏览器会放弃对它们的支持。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.