如何在ReactJS中获得视口高度?在正常的JavaScript中使用

window.innerHeight()

但是使用ReactJS,我不确定如何获得这些信息。我的理解是

ReactDOM.findDomNode()

仅适用于已创建的组件。然而,对于文档或body元素,情况并非如此,它们可以为我提供窗口的高度。


当前回答

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

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

你也可以“堆叠”hoc,如果你有另一个你需要使用,例如withthrouter (withWindowDimensions(MyComponent))

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

其他回答

美好的一天,

我知道我来晚了,但让我告诉你我的答案。

const [windowSize, setWindowSize] = useState(null)

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

    window.addEventListener('resize', handleResize)

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

欲了解更多详情,请访问https://usehooks.com/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;
}

使用useEffect很简单

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

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

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

你也可以“堆叠”hoc,如果你有另一个你需要使用,例如withthrouter (withWindowDimensions(MyComponent))

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

用一点打字稿

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