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

Javascript 获取ReactJS中的视口/窗口高度,javascript,reactjs,window,viewport,Javascript,Reactjs,Window,Viewport,如何在ReactJS中获取视口高度?在普通JavaScript中,我使用 window.innerHeight() 但是使用ReactJS,我不知道如何获取这些信息。我的理解是 ReactDOM.findDomNode() 仅适用于已创建的零部件。但是,文档或主体元素的情况并非如此,它们可以提供窗口的高度。使用挂钩(React16.8.0+) 创建一个useWindowDimensionshook import { useState, useEffect } from 'react'; f

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

window.innerHeight()
但是使用ReactJS,我不知道如何获取这些信息。我的理解是

ReactDOM.findDomNode()
仅适用于已创建的零部件。但是,
文档
主体
元素的情况并非如此,它们可以提供窗口的高度。

使用挂钩(React
16.8.0+

创建一个
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;
}

之后,您就可以在这样的组件中使用它了

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

  return (
    <div>
      width: {width} ~ height: {height}
    </div>
  );
}
const组件=()=>{
const{height,width}=useWindowDimensions();
返回(
宽度:{width}~高度:{height}
);
}

原始答案

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

如你所见

设置道具

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


这个答案与Jabran Saeed的类似,只是它也处理窗口大小调整。我是从你那儿得到的

您也可以尝试以下方法:

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

我只是花了一些时间认真思考了一些关于React和滚动事件/位置的事情-因此对于那些仍在寻找的人,我发现了以下几点:

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

可以使用window.document.body.offsetHeight找到整个文档(正文)的高度

如果您试图找到文档的高度,并知道何时触底,我会想到以下几点:

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

唷!希望它能帮助别人

@spokedcarp的答案很好,但是如果您需要在多个组件中使用这种逻辑,那么它可能会很乏味。您可以将其重构为一个组件,以使此逻辑更易于重用

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}
                />
            );
        }
    };
}
import React,{Component}来自“React”;
使用WindowDimensions导出默认函数(WrappedComponent){
返回类扩展组件{
状态={宽度:0,高度:0};
componentDidMount(){
this.updateWindowDimensions();
window.addEventListener(“resize”,this.updateWidowDimensions);
}
组件将卸载(){
removeEventListener(“resize”,this.updateWind维);
}
更新维度=()=>{
this.setState({width:window.innerWidth,height:window.innerHeight});
};
render(){
返回(
);
}
};
}
然后在您的主要组件中:

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);
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
从“./withWindowDimensions.jsx”导入withWindowDimensions;
类MyComponent扩展组件{
render(){
如果(this.props.isMobileSized)返回,则它是短的;
否则返回它不短

; } 使用WindowDimensions导出默认值(MyComponent);
如果需要使用另一个HOC,也可以“堆叠”HOC,例如使用路由器(使用WindowDimensions(MyComponent))


编辑:我会选择React hook novely(),因为@spheredcarp和@Jamesl的一些答案都非常出色。但是,在我的例子中,我需要一个组件,其高度可以扩展整个窗口高度,在渲染时是有条件的……但是在
render()中调用HOC
重新呈现整个子树。BAAAD

另外,我不想把这些值作为道具,只是想要一个父级
div
,它将占据整个屏幕的高度(或宽度,或两者兼而有之)

所以我编写了一个父组件,提供了一个全高(和/或全宽)的div.Boom

用例:

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>
    )
类MyPage扩展了React.Component{
render(){
const{data,…rest}=this.props
返回数据(
//我的应用程序使用了一些模板,如果你手工修改容器的高度,这些模板会表现得很糟糕,所以这里不要考虑容器的高度。
耶!用一些数据呈现页面。
) : (
//您现在处于全高度div中,因此容器将垂直对齐
页面加载!
)
以下是组件:

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);
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
import React,{Component}来自“React”
从“道具类型”导入道具类型
类FullArea扩展组件{
建造师(道具){
超级(道具)
此.state={
宽度:0,
高度:0,,
}
this.getStyles=this.getStyles.bind(this)
this.updateWindowDimensions=this.updateWindowDimensions.bind(this)
}
componentDidMount(){
this.updateWind维()
window.addEventListener('resize',this.updateWidowDimensions)
}
组件将卸载(){
window.removeEventListener('resize',this.updateWindImmensions)
}
getStyles(垂直、水平){
常量样式={}
如果(垂直){
style.height=`${this.state.height}px`
}
如果(水平){
style.width=`${this.state.width}px`
}
返回样式
}
updateWindowDimensions(){
this.setState({width:window.innerWidth,height:window.innerHeight})
}
render(){
const{vertical,horizontal}=this.props
返回(
{this.props.children}
)
}
}
FullArea.defaultProps={
水平:错,
垂直:假,
}
FullArea.propTypes={
水平:PropTypes.bool,
垂直:PropTypes.bool,
}
导出默认完整区域
我刚刚编辑了支持SSR的,并将其与一起使用(React 16.8.0+):

/hooks/useWindowDimensions.js

从'react'导入{useState,useffect};
导出默认函数useWindowDimensions(){
const hasWindow=窗口类型!=“未定义”;
函数getWindowDimensions(){
const width=hasWindow?window.innerWidth:null;
const height=hasWindow?window.innerHeight:空;
返回{
宽度,
高度,
};
}
常数[风]
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>
    )
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
// 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
   </>
  )
}
const [windowSize, setWindowSize] = useState(null)

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

    window.addEventListener('resize', handleResize)

    return () => window.removeEventListener('resize', handleResize)
}, [])
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);
}, []);
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>
    </>
  );
}
//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);
}