如何在ReactJS中获得视口高度?在正常的JavaScript中使用
window.innerHeight()
但是使用ReactJS,我不确定如何获得这些信息。我的理解是
ReactDOM.findDomNode()
仅适用于已创建的组件。然而,对于文档或body元素,情况并非如此,它们可以为我提供窗口的高度。
如何在ReactJS中获得视口高度?在正常的JavaScript中使用
window.innerHeight()
但是使用ReactJS,我不确定如何获得这些信息。我的理解是
ReactDOM.findDomNode()
仅适用于已创建的组件。然而,对于文档或body元素,情况并非如此,它们可以为我提供窗口的高度。
当前回答
我刚刚编辑了QoP当前的答案以支持SSR,并将其与Next.js (React 16.8.0+)一起使用:
/钩/ 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>
);
}
其他回答
我发现了一个简单的组合QoP和speckledcarp的答案,使用React Hooks和调整大小功能,代码行数略少:
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);
}, []);
哦,是的,确保resize事件是双引号,而不是单引号。这一点让我有点不安;)
你也可以试试这个:
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);
}
我建议使用useSyncExternalStore
import { useSyncExternalStore } from "react";
const store = {
size: {
height: undefined,
width: undefined
}
};
export default function ChatIndicator() {
const { height, width } = useSyncExternalStore(subscribe, getSnapshot);
return (
<h1>
{width} {height}
</h1>
);
}
function getSnapshot() {
if (
store.size.height !== window.innerHeight ||
store.size.width !== window.innerWidth
) {
store.size = { height: window.innerHeight, width: window.innerWidth };
}
return store.size;
}
function subscribe(callback) {
window.addEventListener("resize", callback);
return () => {
window.removeEventListener("resize", callback);
};
}
如果你想试试:https://codesandbox.io/s/vibrant-antonelli-5cecpm
@speckledcarp和@Jamesl的回答都很精彩。然而,在我的例子中,我需要一个组件,其高度可以扩展整个窗口高度,在呈现时有条件....但是在render()中调用HOC会重新渲染整个子树。很糟糕。
另外,我对获取作为道具的值不感兴趣,但只是想要一个父div,将占据整个屏幕的高度(或宽度,或两者)。
所以我写了一个父组件,提供了一个完整的高度(和/或宽度)div。
一个用例:
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
在这里,您可以将投票次数最多的答案包装在一个节点包中(已测试,typescript),以便使用。
安装:
npm i @teambit/toolbox.react.hooks.get-window-dimensions
用法:
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>
</>
);
};