[javascript] Get viewport/window height in ReactJS

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.

This question is related to javascript reactjs window viewport

The answer is


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!


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


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


// 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
   </>
  )
}

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 future details visit https://usehooks.com/useWindowSize/


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

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

with a little typescript

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


@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


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

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

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

Examples related to javascript

need to add a class to an element How to make a variable accessible outside a function? Hide Signs that Meteor.js was Used How to create a showdown.js markdown extension Please help me convert this script to a simple image slider Highlight Anchor Links when user manually scrolls? Summing radio input values How to execute an action before close metro app WinJS javascript, for loop defines a dynamic variable name Getting all files in directory with ajax

Examples related to reactjs

Error: Node Sass version 5.0.0 is incompatible with ^4.0.0 TypeError [ERR_INVALID_ARG_TYPE]: The "path" argument must be of type string. Received type undefined raised when starting react app Template not provided using create-react-app How to resolve the error on 'react-native start' Element implicitly has an 'any' type because expression of type 'string' can't be used to index Invalid hook call. Hooks can only be called inside of the body of a function component How to style components using makeStyles and still have lifecycle methods in Material UI? React Hook "useState" is called in function "app" which is neither a React function component or a custom React Hook function How to fix missing dependency warning when using useEffect React Hook? Unable to load script.Make sure you are either running a Metro server or that your bundle 'index.android.bundle' is packaged correctly for release

Examples related to window

CMD command to check connected USB devices Get viewport/window height in ReactJS the MySQL service on local computer started and then stopped AngularJS $watch window resize inside directive tkinter: Open a new window with a button prompt window.close() doesn't work - Scripts may close only the windows that were opened by it Send parameter to Bootstrap modal window? How do I insert a JPEG image into a python Tkinter window? Installing Python 2.7 on Windows 8 How do I get the offset().top value of an element without using jQuery?

Examples related to viewport

disable viewport zooming iOS 10+ safari? Get viewport/window height in ReactJS What does the shrink-to-fit viewport meta attribute do? What is initial scale, user-scalable, minimum-scale, maximum-scale attribute in meta tag? Mobile overflow:scroll and overflow-scrolling: touch // prevent viewport "bounce" Overflow-x:hidden doesn't prevent content from overflowing in mobile browsers Disable Pinch Zoom on Mobile Web scale fit mobile web content using viewport meta tag div with dynamic min-height based on browser window height What's the point of 'meta viewport user-scalable=no' in the Google Maps API