How to detect if screen size has changed to mobile in React?

前端 未结 5 1575
南方客
南方客 2021-01-30 17:25

I am developing a web app with React and need to detect when the screen size has entered the mobile break-point in order to change the state. Specifically I need my sidenav to b

相关标签:
5条回答
  • 2021-01-30 18:01

    What I did is adding an event listener after component mount:

    componentDidMount() {
        window.addEventListener("resize", this.resize.bind(this));
        this.resize();
    }
    
    resize() {
        this.setState({hideNav: window.innerWidth <= 760});
    }
    
    componentWillUnmount() {
        window.removeEventListener("resize", this.resize.bind(this));
    }
    

    EDIT: To save state updates, I changed the "resize" a bit, just to be updated only when there is a change in the window width.

    resize() {
        let currentHideNav = (window.innerWidth <= 760);
        if (currentHideNav !== this.state.hideNav) {
            this.setState({hideNav: currentHideNav});
        }
    }
    

    UPDATE: Time to use hooks! If you're component is functional, and you use hooks - then you can use the useMediaQuery hook, from react-responsive package.

    import { useMediaQuery } from 'react-responsive';
    
    ...
    
    const isMobile = useMediaQuery({ query: `(max-width: 760px)` });
    

    After using this hook, "isMobile" will be update upon screen resize, and will re-render the component. Much nicer!

    0 讨论(0)
  • 2021-01-30 18:01

    hey I just published a npm package for this issue. Check it out https://www.npmjs.com/package/react-getscreen

    import React, { Component } from 'react';
    import {withGetScreen} from 'react-getscreen'
    
    class Test extends Component {
      render() {
        if (this.props.isMobile()) return <div>Mobile</div>;
        if (this.props.isTablet()) return <div>Tablet</div>;
        return <div>Desktop</div>;
      }
    }
    
    export default withGetScreen(Test);
    
    //or you may set your own breakpoints by providing an options object
    
    const options = {mobileLimit: 500, tabletLimit: 800}
    export default withGetScreen(Test, options);
    
    0 讨论(0)
  • 2021-01-30 18:02

    Using hooks in React(16.8.0+) refering to: https://stackoverflow.com/a/36862446/1075499

    import { useState, useEffect } from 'react';
    
    function getWindowDimensions() {
      const { innerWidth: width, innerHeight: height } = window;
      return {
        width,
        height
      };
    }
    
    export default function useWindowDimensions() {
      const [windowDimensions, setWindowDimensions] = useState(getWindowDimensions());
    
      useEffect(() => {
        function handleResize() {
          setWindowDimensions(getWindowDimensions());
        }
    
        window.addEventListener('resize', handleResize);
        return () => window.removeEventListener('resize', handleResize);
      }, []);
    
      return windowDimensions;
    }
    
    0 讨论(0)
  • 2021-01-30 18:04

    This is the same as @Ben Cohen answer but after attaching your function to eventListner, also remove it on componentWillUnmount

    constructor() {
      super();
      this.state = { screenWidth: null };
      this.updateWindowDimensions = this.updateWindowDimensions.bind(this);
    }
    
    componentDidMount() {
        window.addEventListener("resize", this.updateWindowDimensions());
    }
    
    componentWillUnmount() {
        window.removeEventListener("resize", this.updateWindowDimensions)
    }
    
    updateWindowDimensions() {
       this.setState({ screenWidth: window.innerWidth });
    }
    
    0 讨论(0)
  • 2021-01-30 18:17

    There are multiple ways to archive this first way is with CSS using this class

    @media screen and (max-width: 576px) {}
    

    any class inside this tag will only be visible when the screen is equal or less than 576px

    the second way is to use the event listener

    something like this

     constructor(props)
        {
            super(props);
    
            this.state = {
                isToggle: null
            }
    
            this.resizeScreen = this.resizeScreen.bind(this); 
        }
        
        
         componentDidMount() {
    
            window.addEventListener("resize", this.resizeScreen());
    
        }
        
        
        resizeScreen() {
            if(window.innerWidth === 576)
            {
                this.setState({isToggle:'I was resized'});
            }
            
        }

    even with the event listener I still prefer the CSS way since we can use multiple screen sizes without further js coding.

    I hope this helps!

    0 讨论(0)
提交回复
热议问题