답변:
이 답변은 창 크기 조정도 처리한다는 점을 제외하고 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 };
상태 변수가 유형을 변경하지 않도록해야합니다 ( window.innerWidth가 integer 인 경우 ). IMHO를 이해하기 쉽게 코드를 제외하고는 아무것도 변경하지 않습니다. 답변 해주셔서 감사합니다!
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
방금 SSR 을 지원 하고 Next.js 와 함께 사용 하기 위해 QoP 의 현재 답변 을 편집 했습니다 (React 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를 "스택"할 수도 있습니다. withRouter(withWindowDimensions(MyComponent))
편집 : HOC 및 클래스와 관련된 고급 문제 중 일부를 해결하기 위해 요즘 React 후크 ( 위의 예 )를 사용합니다.
나는 방금 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);
아휴! 그것이 누군가를 돕기를 바랍니다!
// 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)
콜백 인수는 이미 생성자에 의해 바인딩되어 있으므로 제거 할 수 있습니다 .