Answers:
这个答案类似于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 });
}
this.state = { width: 0, height: 0 };
这样,以便状态var不会更改其类型(如果我正确理解window.innerWidth是integer)。除了使代码更易于理解恕我直言之外,不进行任何更改。感谢你的回答!
this.state = { width: window.innerWidth, height: window.innerHeight };
开始?
使用挂钩(反应16.8.0+
)
创建一个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;
}
之后,您将可以像这样在组件中使用它
const Component = () => {
const { height, width } = useWindowDimensions();
return (
<div>
width: {width} ~ height: {height}
</div>
);
}
原始答案
在React中是一样的,您可以window.innerHeight
用来获取当前视口的高度。
正如你可以看到这里
req
道具是否在上可用getInitialProps
。如果是这样,它将在服务器上运行,那么您将没有窗口变量。
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...
}
}
设置道具
AppComponent.propTypes = {
height:React.PropTypes.string
};
AppComponent.defaultProps = {
height:'500px'
};
视口高度现在可以在渲染模板中用作{this.state.height}
height: window.innerHeight || props.height
。这不仅可以简化代码,而且可以消除不必要的状态更改。
componentWillMount
不再推荐使用,请参见reactjs.org/docs/react-component.html#unsafe_componentwillmount
我刚刚编辑了QoP的当前答案以支持SSR,并将其与Next.js结合使用(反应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>
);
}
@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,也可以“堆叠” HOC,例如 withRouter(withWindowDimensions(MyComponent))
我只是花了一些认真的时间来弄清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
});
}
}
(我的导航栏在固定位置为72px,因此使用-72可获得更好的滚动事件触发器)
最后,这是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);
ew!希望它能对某人有所帮助!
// 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
</>
)
}
@speckledcarp和@Jamesl的回答都很棒。但是,就我而言,我需要一个组件,该组件的高度可以扩展整个窗口的高度,在渲染时有条件....但是在内部调用HOC会render()
重新渲染整个子树。BAAAD。
另外,我对获取价值作为道具不感兴趣,只是想要一个父母 div
可以占据整个屏幕高度(或宽度,或两者兼而有之)。
所以我写了一个提供完整高度(和/或宽度)div的Parent组件。繁荣。
用例:
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
您也可以尝试以下操作:
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);
}
.bind(this)
从回调参数中删除它,因为它已经被构造方法绑定了。