How to set a variable to false when ipad orientation is changed from landscape to portrait and vice versa using javascript and react?

stack_overflow

I want to set a variable to false when iPad orientation is changed from landscape to portrait and from portrait to landscape using react and javascript.

I have two state variables isPopupOpen, isClicked set to false initially. when the button is clicked these are set to true. when the user clicks anywhere outside Popup these states isPopupOpen and isClicked are set to false.

below is my code and it works fine.

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>
    }

};

Now the problem is when the user uses iPad in landscape mode clicks a button the popup opens, now without closing popup switches to portrait mode the popup closes on its own. now when the user clicks on the button the popup doesn't show up.

I think the problem here is, when the user switches to portrait mode, the popup closes on its own and the isClicked state value sets to false. but the isPopupOpen state value is still true.

I think since isPopupOpen is passed from other components, its value is not set to false automatically on switching to different modes. whereas isClicked state value is set to false.

How can I solve this problem? How can I set isPopupOpen to false too when the user switches modes. does React.useEffect somehow be used for this case.

Could someone help me with this? thanks.

EDIT:

based on the answer provided I have tried something like this

const onOrientationChange = React.useCallback(() => {
    setIsPopupOpen(false);
}, [setIsPopupOpen]);
React.useEffect(() => {
    window.addEventListener('orientationchange', onOrientationChange);
    return () => {
       window.removeEventListener('orientationchange', onOrientationChange);
    };
}, [onOrientationChange]);

But this still doesn't show the popup.

T.J. Crowder

You can listen for the orientationchange event. Like all event handlers for events that occur outside React's domain, you'd hook it up once in a useEffect hook callback with no dependencies and disconnect it when you get the unmounting callback:

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
);

If you have any of several linting solutions in place, they may complain about your not listing setIsPopupOpen as a dependency in that useEffect call. It should be safe not to do so, because state setters should be stable (not change across the duration of a component's lifecycle). The ones from useState are. Since you're receiving yours via props, you'll need to be sure that that setter is indeed stable (for instance, make sure it's from useState in the component that's using your component).

If you just added it to the dependency array, and it gets changed regularly, you'll get spurious calls saying the orientation changed. It's possible to deal with that if you can't get that guarantee, but it's more work:

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>
    }

};

Note that the window.orientation property is described as "no longer recommended" by MDN, and both the event and the property are described by the compatibility specification. Until or unless the Sensors API happens, though, I can't imagine mobile browsers will drop support for them.

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related

How to check Device Orientation Change From Portrait To Landscape and Vice-Versa in iPad

How to manage portrait and landscape orientation of iPad in Xcode?

UITabbar height and display in iPhone not changing dynamically when rotating from landscape to portrait and vice versa iOS11

Landscape to portrait orientation not working in ipad?

Fragment not using landscape layout when orientation is changed

Supporting Universal App with Portrait Orientation on iPhone and Landscape+Portrait on iPad

Universal application with Portrait orientation for iPhone and Landscape orientation for iPad

Map behavior changes when changed to landscape orientation using fragments

How to add scrolling to the view when screen orientation is changed to landscape?

scrollview position changed from portrait to landscape

How to switch an RxJS Oberservable<boolean> from true to false and vice versa

How to alter Boolean value from true to false and vice-versa

Set Landscape Orientation for iPad Only NOT iPhone

Error Coming when passing props from one component to another and vice - versa in react using typescript

Autolayout iPad for Portrait and Landscape

Passing String variable from Java to JavaScript via Webview (vice versa)

Preserve HTML font-size when iPhone orientation changes from portrait to landscape

How to detect if video is Landscape/portrait when fetched from PHAsset?

How to fix item width in UIcollectionView when moving from portrait to landscape?

ios7 UIProgressView missing when ipad change from Landscape to Portrait

How to export react hook from one file to another, and vice versa?

UIDevice orientation returns portrait when device launches as landscape

App force change orientation landscape to portrait when start purchase flow

How to send data from Python script to JavaScript and vice-versa?

lock iPad to landscape orientation

programmatically change orientation from Landscape to Portrait Mode xamarin IOS

Android custom SurfaceView orientation can't rotate from portrait to landscape

Days after when value changed from positive to negative or vice versa in R

Detecting of flat landscape / portrait orientation