ReactJS में व्यूपोर्ट / विंडो ऊंचाई प्राप्त करें


160

मैं ReactJS में व्यूपोर्ट ऊंचाई कैसे प्राप्त करूं? सामान्य जावास्क्रिप्ट में मैं उपयोग करता हूं

window.innerHeight()

लेकिन ReactJS का उपयोग करते हुए, मुझे यकीन नहीं है कि यह जानकारी कैसे प्राप्त करें। मेरी समझ यह है

ReactDOM.findDomNode()

केवल बनाए गए घटकों के लिए काम करता है। हालांकि यह उस तत्व documentया bodyतत्व के लिए नहीं है , जो मुझे खिड़की की ऊंचाई दे सकता है।

जवाबों:


245

यह उत्तर जबरान सईद के समान है, सिवाय इसके कि यह खिड़की के आकार को भी संभालता है। मुझे यहाँ से मिल गया ।

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

3
आप .bind(this)कॉलबैक तर्कों से हटा सकते हैं क्योंकि यह पहले से ही कंस्ट्रक्टर द्वारा बाध्य है।
स्किमेक्स

1
नाइटपिक: कंस्ट्रक्टर में कोड शायद this.state = { width: 0, height: 0 };ऐसा होना चाहिए कि राज्य के संस्करण उनके प्रकारों को न बदलें (यदि मैं सही ढंग से समझ रहा हूं window.innerWidth पूर्णांक है )। IMHO को समझने के लिए कोड को आसान बनाने के अलावा कुछ भी नहीं बदलता है। जवाब के लिए धन्यवाद!
जॉन्डोडो

1
@johndodo। ओह। संपादित।
speckledcarp

7
this.state = { width: window.innerWidth, height: window.innerHeight };शुरुआत क्यों नहीं की?
गेरबस

1
शायद यह सबसे अच्छा विचार नहीं है, विंडो के आकार की घटना को लक्षित करने के लिए कॉलबैक का उपयोग करें और फिर कॉलबैक के अंदर वैश्विक विंडो ऑब्जेक्ट को फिर से लक्षित करें। प्रदर्शन, पठनीयता और सम्मेलन के लिए, मैं दिए गए ईवेंट मूल्यों का उपयोग करने के लिए इसे अपडेट करने जा रहा हूं।
गोरेडेक्स

176

हुक का उपयोग करना (प्रतिक्रिया 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>
  );
}

काम करने का उदाहरण

मूल उत्तर

यह रिएक्ट में समान है, आप window.innerHeightवर्तमान व्यूपोर्ट की ऊंचाई प्राप्त करने के लिए उपयोग कर सकते हैं ।

जैसा कि आप यहां देख सकते हैं


2
window.innerHeight एक फ़ंक्शन नहीं है, यह एक संपत्ति है
Jairo

2
लगता है कि केविन दानिकोव्स्की ने जवाब को संपादित किया और किसी तरह उस बदलाव को मंजूरी दी गई। यह अब तय हो गया है।
QoP

3
@ यदि यह घटक के अनमाउंट होने पर ईवेंट श्रोता को हटा देता है। इसे cleanupफ़ंक्शन कहा जाता है , आप इसके बारे में यहां
QoP

1
SSR (NextJS) के साथ समान दृष्टिकोण प्राप्त करने के लिए कोई विचार?
रोडेव

1
NextJS पर @roadev, आप यह भी देख सकते हैं कि क्या reqप्रॉप उपलब्ध है getInitialProps। यदि यह है, यह सर्वर पर चल रहा है, तो आपके पास विंडो चर नहीं होंगे।
जियोनीनिड्स

54
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} के रूप में उपलब्ध है


13
यदि ब्राउज़र विंडो का आकार बदलने पर यह समाधान अपडेट नहीं करता
speckledcarp

1
FYI करें, एक कंपोनेंट माउंट के बाद राज्य को अपडेट करना एक दूसरे रेंडर () कॉल को ट्रिगर करेगा और प्रॉपर्टी / लेआउट थ्रैशिंग को जन्म दे सकता है। github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/...
Haukur Kristinsson

1
@HaukurKristinsson इससे कैसे उबरें?
रिचर्ड

1
@JabranSaeed क्यों न सिर्फ आगे बढ़ें और इसे माउंट पर अपडेट करने के बजाय कंस्ट्रक्टर पर ऊंचाई सेट करें? यदि आपको प्रॉपर विचार करने की आवश्यकता है तो आप मूल्य को इस तरह से डिफ़ॉल्ट कर सकते हैं height: window.innerHeight || props.height:। यह न केवल कोड को सरल करेगा बल्कि अनावश्यक राज्य परिवर्तनों को भी हटा देगा।
जॉनी क्यू जूल 13'17

componentWillMountअब अनुशंसित नहीं है, reactjs.org/docs/react-component.html#unsafe_componentwillmount
holmberd

26

मैंने SSR का समर्थन करने और Next.js (प्रतिक्रिया 16.8.0+) के साथ उपयोग करने के लिए QoP का वर्तमान उत्तर संपादित किया है :

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

महान समाधान।
जेरेमी ई

मैंने NextJS के साथ ऐसा करने की कोशिश की लेकिन ऐसा लगता है कि स्क्रीन के आकार के बाद ही इसका सही आकार है। मुझे लगता है कि यह nextJS सर्वर-साइड रेंडरिंग के कारण है। आपके पास कोई विचार है?
हर्षम

15

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

आप HOCs को "स्टैक" भी कर सकते हैं यदि आपके पास कोई दूसरा उपयोग करने की आवश्यकता है, जैसे withRouter(withWindowDimensions(MyComponent))

संपादित करें: मैं आजकल एक प्रतिक्रिया हुक के साथ जाऊंगा ( उदाहरण यहाँ ऊपर ), क्योंकि वे HOC और कक्षाओं के साथ कुछ उन्नत मुद्दों को हल करते हैं।


1
अच्छी नौकरी @James
मनीष शर्मा

8

मैंने अभी कुछ गंभीर समय बिताया है, कुछ चीजों को रिएक्ट और स्क्रॉलिंग इवेंट्स / पोज़िशन्स के साथ बिताया है - इसलिए जो अभी भी देख रहे हैं, उनके लिए यहाँ क्या है:

Viewport ऊंचाई 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('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);

वाह! आशा है कि यह किसी की मदद करता है!


3
// 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
   </>
  )
}

1
ढेर अतिप्रवाह में आपका स्वागत है। बिना किसी स्पष्टीकरण के कोड डंप शायद ही कभी सहायक होते हैं। स्टैक ओवरफ्लो सीखने के बारे में है, नेत्रहीन कॉपी और पेस्ट करने के लिए स्निपेट प्रदान नहीं करना। कृपया अपने प्रश्न को संपादित करें और यह बताएं कि यह ओपी द्वारा प्रदान किए गए कार्यों से बेहतर कैसे काम करता है।
क्रिस

2

@Speckledcarp और @ जेम्स द्वारा जवाब दोनों शानदार हैं। मेरे मामले में, हालाँकि, मुझे एक ऐसे घटक की आवश्यकता थी, जिसकी ऊँचाई पूरी खिड़की की ऊँचाई को बढ़ा सके, रेंडर समय पर सशर्त .... लेकिन भीतर एक एचओसी को कॉल 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

0

आप यह भी आज़मा सकते हैं:

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);
}
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.