Get viewport/window height in ReactJS

JavascriptReactjsWindowViewport

Javascript Problem Overview


How do I get the viewport height in ReactJS? In normal JavaScript I use

window.innerHeight()

but using ReactJS, I'm not sure how to get this information. My understanding is that

ReactDOM.findDomNode()

only works for components created. However this is not the case for the document or body element, which could give me height of the window.

Javascript Solutions


Solution 1 - Javascript

Using Hooks (React 16.8.0+)

Create a useWindowDimensions hook.

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

And after that you'll be able to use it in your components like this

const Component = () => {
  const { height, width } = useWindowDimensions();

  return (
    <div>
      width: {width} ~ height: {height}
    </div>
  );
}

Working example

Original answer

It's the same in React, you can use window.innerHeight to get the current viewport's height.

As you can see here

Solution 2 - Javascript

This answer is similar to Jabran Saeed's, except it handles window resizing as well. I got it from here.

constructor(props) {
  super(props);
  this.state = { width: 0, height: 0 };
  this.updateWindowDimensions = this.updateWindowDimensions.bind(this);
}

componentDidMount() {
  this.updateWindowDimensions();
  window.addEventListener('resize', this.updateWindowDimensions);
}

componentWillUnmount() {
  window.removeEventListener('resize', this.updateWindowDimensions);
}

updateWindowDimensions() {
  this.setState({ width: window.innerWidth, height: window.innerHeight });
}

Solution 3 - Javascript

I've just edited QoP's current answer to support SSR and use it with Next.js (React 16.8.0+):

/hooks/useWindowDimensions.js:

import { useState, useEffect } from 'react';

export default function useWindowDimensions() {

  const hasWindow = typeof window !== 'undefined';

  function getWindowDimensions() {
    const width = hasWindow ? window.innerWidth : null;
    const height = hasWindow ? window.innerHeight : null;
    return {
      width,
      height,
    };
  }

  const [windowDimensions, setWindowDimensions] = useState(getWindowDimensions());

  useEffect(() => {
    if (hasWindow) {
      function handleResize() {
        setWindowDimensions(getWindowDimensions());
      }

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

  return windowDimensions;
}

/yourComponent.js:

import useWindowDimensions from './hooks/useWindowDimensions';

const Component = () => {
  const { height, width } = useWindowDimensions();
  /* you can also use default values or alias to use only one prop: */
  // const { height: windowHeight = 480 } useWindowDimensions();

  return (
    <div>
      width: {width} ~ height: {height}
    </div>
  );
}

Solution 4 - Javascript

class AppComponent extends React.Component {
  
  constructor(props) {
    super(props);
    this.state = {height: props.height};
  }

  componentWillMount(){
    this.setState({height: window.innerHeight + 'px'});
  }

  render() {
    // render your component...
  }
}

> Set the props

AppComponent.propTypes = {
 height:React.PropTypes.string
};

AppComponent.defaultProps = {
 height:'500px'
};

> viewport height is now available as {this.state.height} in rendering template

Solution 5 - Javascript

I found a simple combo of QoP and speckledcarp's answer using React Hooks and resizing features, with slightly less lines of code:

const [width, setWidth]   = useState(window.innerWidth);
const [height, setHeight] = useState(window.innerHeight);
const updateDimensions = () => {
    setWidth(window.innerWidth);
    setHeight(window.innerHeight);
}
useEffect(() => {
    window.addEventListener("resize", updateDimensions);
    return () => window.removeEventListener("resize", updateDimensions);
}, []);

Oh yeah make sure that the resize event is in double quotes, not single. That one got me for a bit ;)

Solution 6 - Javascript

@speckledcarp 's answer is great, but can be tedious if you need this logic in multiple components. You can refactor it as an HOC (higher order component) to make this logic easier to reuse.

withWindowDimensions.jsx

import React, { Component } from "react";

export default function withWindowDimensions(WrappedComponent) {
	return class extends Component {
		state = { width: 0, height: 0 };

		componentDidMount() {
			this.updateWindowDimensions();
			window.addEventListener("resize", this.updateWindowDimensions);
		}

		componentWillUnmount() {
			window.removeEventListener("resize", this.updateWindowDimensions);
		}

		updateWindowDimensions = () => {
			this.setState({ width: window.innerWidth, height: window.innerHeight });
		};

		render() {
			return (
				<WrappedComponent
					{...this.props}
					windowWidth={this.state.width}
					windowHeight={this.state.height}
                    isMobileSized={this.state.width < 700}
				/>
			);
		}
	};
}

Then in your main component:

import withWindowDimensions from './withWindowDimensions.jsx';

class MyComponent extends Component {
  render(){
    if(this.props.isMobileSized) return <p>It's short</p>;
    else return <p>It's not short</p>;
}

export default withWindowDimensions(MyComponent);

You can also "stack" HOCs if you have another you need to use, e.g. withRouter(withWindowDimensions(MyComponent))

Edit: I would go with a React hook nowadays (example above here), as they solve some of the advanced issues with HOCs and classes

Solution 7 - Javascript

with a little typescript

import { useState, useEffect } from 'react';

interface WindowDimentions {
    width: number;
    height: number;
}

function getWindowDimensions(): WindowDimentions {
    const { innerWidth: width, innerHeight: height } = window;

    return {
      width,
      height
    };
  }
  
  export default function useWindowDimensions(): WindowDimentions {
    const [windowDimensions, setWindowDimensions] = useState<WindowDimentions>(
      getWindowDimensions()
    );
  
    useEffect(() => {
      function handleResize(): void {
        setWindowDimensions(getWindowDimensions());
      }
  
      window.addEventListener('resize', handleResize);

      return (): void => window.removeEventListener('resize', handleResize);
    }, []);
  
    return windowDimensions;
  }

Solution 8 - Javascript

Adding this for diversity and clean approach.

This code uses functional style approach. I have used onresize instead of addEventListener as mentioned in other answers.

import { useState, useEffect } from "react";

export default function App() {
  const [size, setSize] = useState({
    x: window.innerWidth,
    y: window.innerHeight
  });
  const updateSize = () =>
    setSize({
      x: window.innerWidth,
      y: window.innerHeight
    });
  useEffect(() => (window.onresize = updateSize), []);
  return (
    <>
      <p>width is : {size.x}</p>
      <p>height is : {size.y}</p>
    </>
  );
}

Solution 9 - Javascript

I just spent some serious time figuring some things out with React and scrolling events / positions - so for those still looking, here's what I found:

The viewport height can be found by using window.innerHeight or by using document.documentElement.clientHeight. (Current viewport height)

The height of the entire document (body) can be found using window.document.body.offsetHeight.

If you're attempting to find the height of the document and know when you've hit the bottom - here's what I came up with:

if (window.pageYOffset >= this.myRefII.current.clientHeight && Math.round((document.documentElement.scrollTop + window.innerHeight)) < document.documentElement.scrollHeight - 72) {
	    this.setState({
	    	trueOrNot: true
	    });
	  } else {
	    this.setState({
	    	trueOrNot: false
	    });
	  }
	}

(My navbar was 72px in fixed position, thus the -72 to get a better scroll-event trigger)

Lastly, here are a number of scroll commands to console.log(), which helped me figure out my math actively.

console.log('window inner height: ', window.innerHeight);

console.log('document Element client hieght: ', document.documentElement.clientHeight);

console.log('document Element scroll hieght: ', document.documentElement.scrollHeight);

console.log('document Element offset height: ', document.documentElement.offsetHeight);

console.log('document element scrolltop: ', document.documentElement.scrollTop);

console.log('window page Y Offset: ', window.pageYOffset);

console.log('window document body offsetheight: ', window.document.body.offsetHeight);

Whew! Hope it helps someone!

Solution 10 - Javascript

Good day,

I know I am late to this party, but let me show you my answer.

const [windowSize, setWindowSize] = useState(null)

useEffect(() => {
    const handleResize = () => {
        setWindowSize(window.innerWidth)
    }

    window.addEventListener('resize', handleResize)

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

for further details please visit https://usehooks.com/useWindowSize/

Solution 11 - Javascript

Using Hooks:

using useLayoutEffect is more efficient here:

import { useState, useLayoutEffect } from 'react';

function getWindowDimensions() {
  const { innerWidth: width, innerHeight: height } = window;
  return {
    width,
    height
  };
}

export default function useWindowDimensions() {
  const [windowDimensions, setWindowDimensions] = useState(getWindowDimensions());

  useLayoutEffect(() => {
    function handleResize() {
      setWindowDimensions(getWindowDimensions());
    }

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

  return windowDimensions;
}

usage:

const { height, width } = useWindowDimensions();

Solution 12 - Javascript

// just use (useEffect). every change will be logged with current value
import React, { useEffect } from "react";

export function () {
  useEffect(() => {
    window.addEventListener('resize', () => {
      const myWidth  = window.innerWidth;
      console.log('my width :::', myWidth)
   })
  },[window])

  return (
    <>
      enter code here
   </>
  )
}

Solution 13 - Javascript

Answers by @speckledcarp and @Jamesl are both brilliant. In my case, however, I needed a component whose height could extend the full window height, conditional at render time.... but calling a HOC within render() re-renders the entire subtree. BAAAD.

Plus, I wasn't interested in getting the values as props but simply wanted a parent div that would occupy the entire screen height (or width, or both).

So I wrote a Parent component providing a full height (and/or width) div. Boom.

A use case:

class MyPage extends React.Component {
  render() {
    const { data, ...rest } = this.props

    return data ? (
      // My app uses templates which misbehave badly if you manually mess around with the container height, so leave the height alone here.
      <div>Yay! render a page with some data. </div>
    ) : (
      <FullArea vertical>
        // You're now in a full height div, so containers will vertically justify properly
        <GridContainer justify="center" alignItems="center" style={{ height: "inherit" }}>
          <GridItem xs={12} sm={6}>
            Page loading!
          </GridItem>
        </GridContainer>
      </FullArea>
    )

Here's the component:

import React, { Component } from 'react'
import PropTypes from 'prop-types'

class FullArea extends Component {
  constructor(props) {
    super(props)
    this.state = {
      width: 0,
      height: 0,
    }
    this.getStyles = this.getStyles.bind(this)
    this.updateWindowDimensions = this.updateWindowDimensions.bind(this)
  }

  componentDidMount() {
    this.updateWindowDimensions()
    window.addEventListener('resize', this.updateWindowDimensions)
  }

  componentWillUnmount() {
    window.removeEventListener('resize', this.updateWindowDimensions)
  }

  getStyles(vertical, horizontal) {
    const styles = {}
    if (vertical) {
      styles.height = `${this.state.height}px`
    }
    if (horizontal) {
      styles.width = `${this.state.width}px`
    }
    return styles
  }

  updateWindowDimensions() {
    this.setState({ width: window.innerWidth, height: window.innerHeight })
  }

  render() {
    const { vertical, horizontal } = this.props
    return (
      <div style={this.getStyles(vertical, horizontal)} >
        {this.props.children}
      </div>
    )
  }
}

FullArea.defaultProps = {
  horizontal: false,
  vertical: false,
}

FullArea.propTypes = {
  horizontal: PropTypes.bool,
  vertical: PropTypes.bool,
}

export default FullArea

Solution 14 - Javascript

You can create custom hooks like this: useWindowSize()

import { useEffect, useState } from "react";
import { debounce } from "lodash";

const getWindowDimensions = () => {
  const { innerWidth: width, innerHeight: height } = window;
  return { width, height };
};

export function useWindowSize(delay = 0) {
  const [windowDimensions, setWindowDimensions] = useState(
    getWindowDimensions()
  );

  useEffect(() => {
    function handleResize() {
      setWindowDimensions(getWindowDimensions());
    }
    const debouncedHandleResize = debounce(handleResize, delay);
    window.addEventListener("resize", debouncedHandleResize);
    return () => window.removeEventListener("resize", debouncedHandleResize);
  }, [delay]);

  return windowDimensions;
}

Solution 15 - Javascript

This is how you can implement it and get the window width and height on real time inside React functional components:

import React, {useState, useEffect} from 'react' 
const Component = () => {
  const [windowWidth, setWindowWidth] = useState(0)
  const [windowHeight, setWindowHeight] = useState(0)
  
  useEffect(() => {
    window.addEventListener('resize', e => {
      setWindowWidth(window.innerWidth);
    });
  }, [window.innerWidth]);

  useEffect(() => {
    window.addEventListener('resize', e => {
      setWindowHeight(window.innerHeight);
    });
  }, [window.innerHeight]);

  return(
    <h3>Window width is: {windowWidth} and Height: {windowHeight}</h3>
  )
}

Solution 16 - Javascript

I've updated the code with a slight variation by wrapping the getWindowDimensions function in useCallback

import { useCallback, useLayoutEffect, useState } from 'react';

export default function useWindowDimensions() {

    const hasWindow = typeof window !== 'undefined';

    const getWindowDimensions = useCallback(() => {
        const windowWidth = hasWindow ? window.innerWidth : null;
        const windowHeight = hasWindow ? window.innerHeight : null;

        return {
            windowWidth,
            windowHeight,
        };
    }, [hasWindow]);

    const [windowDimensions, setWindowDimensions] = useState(getWindowDimensions());

    useLayoutEffect(() => {
        if (hasWindow) {
            function handleResize() {
                setWindowDimensions(getWindowDimensions());
            }

            window.addEventListener('resize', handleResize);
            return () => window.removeEventListener('resize', handleResize);
        }
    }, [getWindowDimensions, hasWindow]);

    return windowDimensions;
}

Solution 17 - Javascript

You can also try this:

constructor(props) {
        super(props);
        this.state = {height: props.height, width:props.width};
      }

componentWillMount(){
          console.log("WINDOW : ",window);
          this.setState({height: window.innerHeight + 'px',width:window.innerWidth+'px'});
      }

render() {
        console.log("VIEW : ",this.state);
}

Solution 18 - Javascript

Simple way to keep current dimensions in the state, even after window resize:

//set up defaults on page mount
componentDidMount() {
  this.state = { width: 0, height: 0 };
  this.getDimensions(); 

  //add dimensions listener for window resizing
  window.addEventListener('resize', this.getDimensions); 
}

//remove listener on page exit
componentWillUnmount() {
  window.removeEventListener('resize', this.getDimensions); 
}

//actually set the state to the window dimensions
getDimensions = () => {
  this.setState({ width: window.innerWidth, height: window.innerHeight });
  console.log(this.state);
}

Solution 19 - Javascript

It is simple to get with useEffect

useEffect(() => {
    window.addEventListener("resize", () => {
        updateDimention({ 
            ...dimension, 
            width: window.innerWidth, 
            height: window.innerHeight 
        });
        console.log(dimension);
    })
})

Solution 20 - Javascript

As answer from: bren but hooking useEffect to [window.innerWidth]

const [dimension, updateDimention] = useState();
  
  useEffect(() => {
    window.addEventListener("resize", () => {
        updateDimention({ 
            ...dimension, 
            width: window.innerWidth, 
            height: window.innerHeight 
        });
       
    })
},[window.innerWidth]);

 console.log(dimension);

Solution 21 - Javascript

React native web has a useWindowDimensions hook that is ready to be used:

    import { useWindowDimensions } from "react-native";
    const dimensions = useWindowDimensions()

Solution 22 - Javascript

Here you have the most voted answer wrapped in a node package (tested, typescript) ready to use.

Install:

npm i @teambit/toolbox.react.hooks.get-window-dimensions

Usage:

import React from 'react';
import { useWindowDimensions } from '@teambit/toolbox.react.hooks.get-window-dimensions';

const MyComponent = () => {
  const { height, width } = useWindowDimensions();

  return (
    <>
      <h1>Window size</h1>
      <p>Height: {height}</p>
      <p>Width: {width}</p>
    </>
  );
};

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionJabran SaeedView Question on Stackoverflow
Solution 1 - JavascriptQoPView Answer on Stackoverflow
Solution 2 - JavascriptspeckledcarpView Answer on Stackoverflow
Solution 3 - JavascriptgiovannipdsView Answer on Stackoverflow
Solution 4 - JavascriptJabran SaeedView Answer on Stackoverflow
Solution 5 - JavascriptJ.E.C.View Answer on Stackoverflow
Solution 6 - JavascriptJames L.View Answer on Stackoverflow
Solution 7 - JavascriptMatthew BarndenView Answer on Stackoverflow
Solution 8 - JavascriptAklesh SakuniaView Answer on Stackoverflow
Solution 9 - Javascriptthielr7View Answer on Stackoverflow
Solution 10 - JavascriptAljohn YamaroView Answer on Stackoverflow
Solution 11 - Javascriptfoad abdollahiView Answer on Stackoverflow
Solution 12 - JavascriptJoabeView Answer on Stackoverflow
Solution 13 - JavascriptthclarkView Answer on Stackoverflow
Solution 14 - JavascriptJason JinView Answer on Stackoverflow
Solution 15 - JavascriptYaser AZView Answer on Stackoverflow
Solution 16 - JavascriptGunzzView Answer on Stackoverflow
Solution 17 - JavascriptShubham VermaView Answer on Stackoverflow
Solution 18 - JavascriptGavinBelsonView Answer on Stackoverflow
Solution 19 - JavascriptDeepak VishwakarmaView Answer on Stackoverflow
Solution 20 - Javascriptuser14570759View Answer on Stackoverflow
Solution 21 - Javascriptpl709View Answer on Stackoverflow
Solution 22 - JavascriptJonatan KruszewskiView Answer on Stackoverflow