admin管理员组文章数量:1202334
I want to detect screen orientation changes using the event orientationchange
, which is supported by all major mobile browsers.
I add the event listener in componentDidMount
and set the state from inside the event callback.
However, I see that when the event first fires as a result of change from portrait to landscape the state is not updated to landscape. Then when I change the orientation from landscape back to portrait, the state says the orientation is landscape. After this each time I change the orientation the state always says the opposite of the actual orientation. I'm not sure if I should be using some lifecycle react method or my detection is not good.
I tested the code using Chrome developer tools Toggle device toolbar
.
This is my code:
import React from 'react';
class AppInfo extends React.Component {
state = {
screenOrientation: 'portrait'
}
isPortraitMode = () => {
console.log(this.state);
const { screenOrientation } = this.state;
return screenOrientation === 'portrait';
}
setScreenOrientation = () => {
if (window.matchMedia("(orientation: portrait)").matches) {
console.log('orientation: portrait');
this.setState({
screenOrientation: 'portrait'
});
}
if (window.matchMedia("(orientation: landscape)").matches) {
console.log('orientation: landscape');
this.setState({
screenOrientation: 'landscape'
});
}
}
componentDidMount() {
window.addEventListener('orientationchange', this.setScreenOrientation);
}
render() {
console.log(`orientation: from render: isPortraitMode = ${this.isPortraitMode()}`);
<div>
Hello
</div>
}
}
export default AppInfo;
I want to detect screen orientation changes using the event orientationchange
, which is supported by all major mobile browsers.
I add the event listener in componentDidMount
and set the state from inside the event callback.
However, I see that when the event first fires as a result of change from portrait to landscape the state is not updated to landscape. Then when I change the orientation from landscape back to portrait, the state says the orientation is landscape. After this each time I change the orientation the state always says the opposite of the actual orientation. I'm not sure if I should be using some lifecycle react method or my detection is not good.
I tested the code using Chrome developer tools Toggle device toolbar
.
This is my code:
import React from 'react';
class AppInfo extends React.Component {
state = {
screenOrientation: 'portrait'
}
isPortraitMode = () => {
console.log(this.state);
const { screenOrientation } = this.state;
return screenOrientation === 'portrait';
}
setScreenOrientation = () => {
if (window.matchMedia("(orientation: portrait)").matches) {
console.log('orientation: portrait');
this.setState({
screenOrientation: 'portrait'
});
}
if (window.matchMedia("(orientation: landscape)").matches) {
console.log('orientation: landscape');
this.setState({
screenOrientation: 'landscape'
});
}
}
componentDidMount() {
window.addEventListener('orientationchange', this.setScreenOrientation);
}
render() {
console.log(`orientation: from render: isPortraitMode = ${this.isPortraitMode()}`);
<div>
Hello
</div>
}
}
export default AppInfo;
Share
Improve this question
asked Apr 13, 2019 at 8:25
hitchhikerhitchhiker
1,3196 gold badges25 silver badges57 bronze badges
2
- 1 You might wanna see this answer - stackoverflow.com/a/36087703/1263904 – pritam Commented Apr 13, 2019 at 14:14
- stackoverflow.com/a/64559463/9444013 – shammi Commented Oct 27, 2020 at 17:08
5 Answers
Reset to default 7Here is an implementation using hooks for react that tracks screen orientation using a custom hook from GitHub for obtaining and tracking orientation. It creates the event listener every time the component is mounted using useEffect and it shuts off the listener everytime the component is dismounted:
import {useState, useEffect} from 'react'
const getOrientation = () =>
window.screen.orientation.type
const useScreenOrientation = () => {
const [orientation, setOrientation] =
useState(getOrientation())
const updateOrientation = event => {
setOrientation(getOrientation())
}
useEffect(() => {
window.addEventListener(
'orientationchange',
updateOrientation
)
return () => {
window.removeEventListener(
'orientationchange',
updateOrientation
)
}
}, [])
return orientation
}
export default useScreenOrientation
In my Android mobile the two values for orientation are: 'portrait-primary' and 'landscape-secondary'. In my Ubuntu system it is: 'landscape-primary'. In my Windows 10 Surface Book 2 laptop mode: 'protrait-primary'. Doesn't handle the switch to tablet well. And it doesn't detect the orientation change at all. All this is under Chrome v 99.0.4844.84 (official build) (64 bit). The Mac OS Monterey v 12.2.1 reports 'landscape-primary' same version of Chrome.
orientationchange has been deprecated and it might or might not work in some browsers. Best bet now is to use one of the following options:
window.screen.orientation.addEventListener('change', function(e) { ... })
window.screen.orientation.onchange = function(e) { ... }
This way you can put whatever logic you want in the callback part of the listener, react or not.
You could try triggering it with the "resize" event instead, as some devices don't provided the orientationchange event, but do fire the window's resize event.
window.addEventListener("resize", this.setScreenOrientation);
Your program works just fine, you just need to log it like this:
this.setState({screenOrientation: 'landscape'}, console.log('orientation: landscape'))
The reason behind it is that call to setState isn't synchronous but setState(updater, callback) is an async function and it takes the callback as second argument.
Here's a shorter and newer version hook, modified from the Answer:
// use-screen-orientation.js
import {useState, useEffect} from 'react';
const getOrientation = () => screen.orientation.type;
export const useScreenOrientation = () => {
const [orientation, setOrientation] = useState(getOrientation());
useEffect(() => {
const handleOrientationChange = () => setOrientation(getOrientation());
screen.orientation.addEventListener('change', handleOrientationChange);
return () => screen.orientation.removeEventListener('change', handleOrientationChange);
}, []);
return orientation;
};
Usage
import React from "react";
import {useScreenOrientation} from "@/hooks/use-screen-orientation";
const Demo= () => {
const screenOrientation = useScreenOrientation();
return (
<p>Screen orientation is: {screenOrientation}</p>
)
}
It will return string
type from:
one of portrait-primary
, portrait-secondary
, landscape-primary
, or landscape-secondary
See also in here
本文标签:
版权声明:本文标题:javascript - How to detect screen orientation in mobile website when using react js and orientationchange event? - Stack Overflo 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1738650152a2104822.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论