React conditionally render based on viewport size

后端 未结 4 2043
太阳男子
太阳男子 2021-01-30 11:24

This should be an easy one for you React monsters. :) I have the condition written but I can\'t figure out how to handle the viewport size in my constructor for the condition to

相关标签:
4条回答
  • 2021-01-30 12:03

    Just to post a recent update here after I had the same issue, but set it up using a functional component and the useEffect / useState React Hooks:

    const MyFunction = () => {
      const [isDesktop, setDesktop] = useState(window.innerWidth > 1450);
    
      const updateMedia = () => {
        setDesktop(window.innerWidth > 1450);
      };
    
      useEffect(() => {
        window.addEventListener("resize", updateMedia);
        return () => window.removeEventListener("resize", updateMedia);
      });
    
      return (
        <div>
          {isDesktop ? (
            <div>I show on 1451px or higher</div>
          ) : (
            <div>I show on 1450px or lower</div>
          )}
        </div>
      );
    }
    
    0 讨论(0)
  • 2021-01-30 12:07
    class My Class extends React.Component {
      constructor(props) {
          super(props);
          this.state = {
              isDesktop: window.innerHeight > 1450,
          };
      }
    
      render() {
          const isDesktop = this.state.isDesktop;
    
          return (
              <div>
                  {isDesktop ? (
                      <div>I show on 1451px or higher</div>
                  ) : (
                      <div>I show on 1450px or lower</div>
                  )}
              </div>
          );
      }}
    

    Here more info Get viewport/window height in ReactJS

    0 讨论(0)
  • 2021-01-30 12:09

    Perhaps I am suppposed to work it with ComponentWillMount or ComponentDidMount

    Yes, you need to listen for resize event and update internal state on change. You can do it by adding event handler when component mounts. Try full example here.

    class App extends React.Component {
      constructor(props) {
        super(props);
        this.state = {
          isDesktop: false //This is where I am having problems
        };
    
        this.updatePredicate = this.updatePredicate.bind(this);
      }
      componentDidMount() {
        this.updatePredicate();
        window.addEventListener("resize", this.updatePredicate);
      }
    
      componentWillUnmount() {
        window.removeEventListener("resize", this.updatePredicate);
      }
    
      updatePredicate() {
        this.setState({ isDesktop: window.innerWidth > 1450 });
      }
    
      render() {
        const isDesktop = this.state.isDesktop;
    
        return (
          <div>
            {isDesktop ? (
              <div>I show on 1451px or higher</div>
            ) : (
              <div>I show on 1450px or lower</div>
            )}
          </div>
        );
      }
    }
    
    0 讨论(0)
  • 2021-01-30 12:09

    the issue with your code is that it only works if the resizing happens, here I have the handleWindowResiz function will set the width to the window.innerWidth and compares it to the breakPoint to conditionally render your UI, if the user resizes the screen the event listener will be triggered and the handleWindowResiz will be called and it will reset the width to the new window.innerWidth and you get your desired UI. So the UI is always rendered correctly when the component is first rendered and when the user resizes the screen width.

    const MyFunction = () => {
    
      const [width, setWidth] = React.useState(window.innerWidth);
      const breakPoint = 1450;
    
     
    
      useEffect(() => {
       const handleWindowResize = () => setWidth(window.innerWidth);
       window.addEventListener("resize", handleWindowResize);
    
        
       return () => window.removeEventListener("resize", handleWindowResize);
      },[]);
    
      return (
        <div>
          {width > breakPoint? (
            <div>I show on 1451px or higher</div>
          ) : (
            <div>I show on 1450px or lower</div>
          )}
        </div>
      );
    }
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>

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