ReactJS: 如何确定应用程序正在移动或桌面浏览器上查看

在 ReactJS 中,有没有一种方法可以确定网站是在手机上还是桌面上浏览的?因为,根据不同的设备,我想渲染不同的东西。

谢谢你

136532 次浏览

React doesn't do this, React is only the View in MVC. Determination logic (controlling what SHOULD be viewed) is the role of the Controller. React doesn't implement a controller but thinks that should be done by the rest of the application, so you should add some other code controlling the context of the React component or even using different components for different devices.

What you are looking for is called react-responsive. You can find it here

Here is how to use quick guide from their repo:

var MediaQuery = require('react-responsive');


var A = React.createClass({
render: function(){
return (
<div>
<div>Device Test!</div>


<MediaQuery minDeviceWidth={1224}>
<div>You are a desktop or laptop</div>
</MediaQuery>
<MediaQuery maxDeviceWidth={1224}>
<div>You are a tablet or mobile phone</div>
</MediaQuery>


<MediaQuery orientation='portrait'>
<div>You are portrait</div>
</MediaQuery>
<MediaQuery orientation='landscape'>
<div>You are landscape</div>
</MediaQuery>


<MediaQuery minResolution='2dppx'>
<div>You are retina</div>
</MediaQuery>
</div>
);
}
});

I used this method for React and it works great in 2020. Thanks @Anubahav Gupta

npm install react-responsive --save

Then create component:

import React, { Fragment, Component } from 'react';
import MediaQuery from 'react-responsive';


class MyMediaQuery extends Component {
render() {
return (
<Fragment>
<div>Device Test!</div>


<MediaQuery minDeviceWidth={1224}>
<div>You are a desktop or laptop</div>
</MediaQuery>
<MediaQuery maxDeviceWidth={1224}>
<div>You are a tablet or mobile phone</div>
</MediaQuery>


<MediaQuery orientation='portrait'>
<div>You are portrait</div>
</MediaQuery>
<MediaQuery orientation='landscape'>
<div>You are landscape</div>
</MediaQuery>


<MediaQuery minResolution='2dppx'>
<div>You are retina</div>
</MediaQuery>
</Fragment>
);
}
}


export default MyMediaQuery;

It works as-is on any page loaded but can also be imported into another file with:

import MyMediaQuery from '.newFileName';

Then used anywhere as:

<MyMediaQuery />

You can use React Device Detect Package

This package uses the user-agent of the browser rather than the screen size.

This can be helpful when wanting to display different things if on desktop vs mobile or certain links based on the device

Installation

To install, you can use npm or yarn:

# For NPM:
npm install react-device-detect --save


# For Yarn
yarn add react-device-detect

Usage

Example:

import {BrowserView, MobileView} from 'react-device-detect';


const MyComponent = () => {
return (
<>
<BrowserView>
<h1>This is rendered only in browser</h1>
</BrowserView>
<MobileView>
<h1>This is rendered only on mobile</h1>
</MobileView>
</>
);
};

if you don't need a view, you can use isMobile for conditional rendering

import {isMobile} from 'react-device-detect';


const MyComponent = () => {
if(isMobile) {
return (
<div> This content is available only on mobile</div>
)
}
return (
<div> content... </div>
);
};

Taken from React Device Detect README with a little modification

Why to complicate things when you can use one line of vanilla javascript code?

Use window.screen object to get width of current screen. For example window.screen.width will return value of current width of client in pixels.

Use it inside if (window.screen.width >= 1280) { /* conditional statements */ }

I hope that it helps. Thank you :-)

Simple solution using react hooks

const [width, setWidth] = useState<number>(window.innerWidth);


function handleWindowSizeChange() {
setWidth(window.innerWidth);
}
useEffect(() => {
window.addEventListener('resize', handleWindowSizeChange);
return () => {
window.removeEventListener('resize', handleWindowSizeChange);
}
}, []);


const isMobile = width <= 768;

I further enhanced Volobot's answer. I'd created a hook as below and it works like charm :)

import React, {useEffect, useState} from "react";


const useCheckMobileScreen = () => {
const [width, setWidth] = useState(window.innerWidth);
const handleWindowSizeChange = () => {
setWidth(window.innerWidth);
}


useEffect(() => {
window.addEventListener('resize', handleWindowSizeChange);
return () => {
window.removeEventListener('resize', handleWindowSizeChange);
}
}, []);


return (width <= 768);
}


export default useCheckMobileScreen

This is not specifc to React but here is my js fonction:

export const isMobile = () => window.matchMedia && window.matchMedia("(max-width: 480px)").matches
const getNumberDesignRequest = screenWidth => {
let numberDesignRequest = 20
if (screenWidth >= 1280 && screenWidth < 1525) {
numberDesignRequest = 21
}
  

return numberDesignRequest
}


const ScreenWidth = () => {
const [screenWidth, setScreenWidth] = useState(window.innerWidth)


useLayoutEffect(() => {
const handleResize = () => {
const { innerWidth } = window
setScreenWidth(innerWidth)
}


window.addEventListener('resize', debounce(handleResize, 1000))
return () => window.removeEventListener('resize', handleResize)
}, [])


return screenWidth
}


const FuzzySearch = () => {
const screenWidth = ScreenWidth()
const numberDesignRequest = getNumberDesignRequest(screenWidth)

Create a Custom Hook and Listen to Resize, load, orientationchange and reload will rerender the component where you have used this hook.

import { useEffect, useState } from 'react';


const useIsMobile = (breakpoint = 640) => {
const checkForDevice = () => window.innerWidth < breakpoint;


const [isMobile, setIsMobile] = useState(checkForDevice());


useEffect(() => {
const handlePageResized = () => {
setIsMobile(checkForDevice());
};


if (typeof window !== 'undefined') {
window.addEventListener('resize', handlePageResized);
window.addEventListener('orientationchange', handlePageResized);
window.addEventListener('load', handlePageResized);
window.addEventListener('reload', handlePageResized);
}


return () => {
if (typeof window !== 'undefined') {
window.removeEventListener('resize', handlePageResized);
window.removeEventListener('orientationchange', handlePageResized);
window.removeEventListener('load', handlePageResized);
window.removeEventListener('reload', handlePageResized);
}
};
}, []);


return {
isMobile,
};
};


export default useIsMobile;

Tablets has big screens but they act like mobile phones, so if you want to detect touch screen instead of the size of the screen:

const isTouchScreenDevice = () => {
try{
document.createEvent('TouchEvent');
return true;
}catch(e){
return false;
}
}

The solution for this is to check the size of the screen

const width = window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth;
const MAX_WIDTH_FOR_MOBILE = 900;

Now check the width of the screen with the max width

return (
width < MAX_WIDTH_FOR_MOBILE ? <Mobile /> : <Desktop />
)