Javascript 在 ReactJS 中获取视口/窗口高度

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/36862334/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 19:39:03  来源:igfitidea点击:

Get viewport/window height in ReactJS

javascriptreactjswindowviewport

提问by Jabran Saeed

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

如何在 ReactJS 中获取视口高度?在普通的 JavaScript 中,我使用

window.innerHeight()

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

但是使用 ReactJS,我不确定如何获取此信息。我的理解是

ReactDOM.findDomNode()

only works for components created. However this is not the case for the documentor bodyelement, which could give me height of the window.

仅适用于创建的组件。然而,这不是documentorbody元素的情况,它可以给我窗口的高度。

采纳答案by Jabran Saeed

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

视口高度现在可用作渲染模板中的 {this.state.height}

回答by speckledcarp

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

这个答案类似于 Jabran Saeed 的,除了它也处理窗口大小调整。我从这里得到的。

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

回答by QoP

Using Hooks (React 16.8.0+)

使用钩子 (React 16.8.0+)

Create a useWindowDimensionshook.

创建一个useWindowDimensions钩子。

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.innerHeightto get the current viewport's height.

在 React 中也是如此,您可以使用它window.innerHeight来获取当前视口的高度。

As you can see here

正如你在这里看到的

回答by giovannipds

I've just edited QoP's current answerto support SSRand use it with Next.js(React 16.8.0+):

我刚刚编辑了QoP当前答案以支持SSR并将其与Next.js(React 16.8.0+) 一起使用:

/hooks/useWindowDimensions.js:

/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:

/你的组件.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>
  );
}

回答by James L.

@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.

@speckledcarp 的回答很好,但如果您需要在多个组件中使用此逻辑,则可能会很乏味。您可以将其重构为HOC(高阶组件),以使此逻辑更易于重用。

withWindowDimensions.jsx

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

如果您需要使用另一个 HOC,您也可以“堆叠” HOC,例如 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

编辑:我现在会使用 React 钩子(这里上面的例子),因为它们解决了HOC 和类的一些高级问题

回答by thielr7

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:

我只是花了一些时间用 React 和滚动事件/位置来解决一些问题 - 所以对于那些仍在寻找的人,这是我发现的:

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

可以使用 window.innerHeight 或使用 document.documentElement.clientHeight 找到视口高度。(当前视口高度)

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

可以使用 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)

(我的导航栏在固定位置是 72px,因此 -72 以获得更好的滚动事件触发器)

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

最后,这里有一些 console.log() 的滚动命令,它们帮助我积极地计算出我的数学。

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!

哇!希望它可以帮助某人!

回答by thclark

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.

@speckledcarp 和 @Jamesl 的回答都很精彩。然而,在我的情况下,我需要一个组件,其高度可以扩展整个窗口的高度,在渲染时有条件......但是在内部调用 HOC 会render()重新渲染整个子树。巴阿德。

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

另外,我对将值作为道具不感兴趣,只是想要一个div占据整个屏幕高度(或宽度,或两者)的父级。

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

所以我写了一个提供全高(和/或宽度)div 的父组件。繁荣。

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

回答by Joabe

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

回答by Shubham Verma

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