ReactJSでビューポートの高さを取得するにはどうすればよいですか?私が使用する通常のJavaScriptでは
window.innerHeight()
しかし、ReactJSを使用すると、この情報を取得する方法がわかりません。私の理解は
ReactDOM.findDomNode()
作成されたコンポーネントに対してのみ機能します。ただし、これはdocument
or body
要素には当てはまりません。これにより、ウィンドウの高さがわかります。
ReactJSでビューポートの高さを取得するにはどうすればよいですか?私が使用する通常のJavaScriptでは
window.innerHeight()
しかし、ReactJSを使用すると、この情報を取得する方法がわかりません。私の理解は
ReactDOM.findDomNode()
作成されたコンポーネントに対してのみ機能します。ただし、これはdocument
or body
要素には当てはまりません。これにより、ウィンドウの高さがわかります。
回答:
この回答は、ウィンドウのサイズ変更も処理することを除いて、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です)。コードを理解しやすくする以外は何も変更しません。答えてくれてありがとう!
this.state = { width: window.innerWidth, height: window.innerHeight };
開始するには?
フックの使用(React 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
QoPの現在の回答を編集してSSRをサポートし、Next.js(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がある場合は、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
});
}
}
(私のnavbarは固定位置で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の回答はどちらも素晴らしいです。しかし、私の場合、レンダリング時に条件付きでウィンドウ全体の高さを拡張できるコンポーネントが必要でした。render()
サブツリー全体が再レンダリングされます。BAAAD。
さらに、私は小道具として値を取得することに興味がなかったが、単に親が欲しかった 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
これを試すこともできます:
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)
コールバック引数はコンストラクタによってすでにバインドされているため、削除することができます。