繁体   English   中英

当ipad方向从横向更改为纵向时如何使用javascript将变量设置为false,反之亦然并做出反应?

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM