ReactJS এ ভিউপোর্ট / উইন্ডো উচ্চতা পান


159

আমি কীভাবে রিঅ্যাক্টজেএসে ভিউপোর্টের উচ্চতা পেতে পারি? সাধারণ জাভাস্ক্রিপ্টে আমি ব্যবহার করি

window.innerHeight()

কিন্তু রিএ্যাকটিজেএস ব্যবহার করে, আমি কীভাবে এই তথ্য পাব তা নিশ্চিত নই। আমার বোঝাপড়া এটি

ReactDOM.findDomNode()

শুধুমাত্র তৈরি উপাদানগুলির জন্য কাজ করে। তবে এটি উপাদান documentবা bodyউপাদানটির ক্ষেত্রে নয় , যা আমাকে উইন্ডোর উচ্চতা দিতে পারে।

উত্তর:


244

এই উত্তরটি জাবরান সা 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 });
}

3
আপনি .bind(this)কলব্যাক যুক্তি থেকে অপসারণ করতে পারেন যেহেতু এটি ইতিমধ্যে নির্মাণকারীর দ্বারা আবদ্ধ।
সাইকিমেক্স

1
নিতপিক: কনস্ট্রাক্টরের কোড সম্ভবত এমন হওয়া উচিত this.state = { width: 0, height: 0 };যাতে রাষ্ট্রের ভারগুলি তাদের প্রকারগুলি পরিবর্তন না করে (যদি আমি সঠিকভাবে বুঝতে পারি উইন্ডো.নিরউইথথ পূর্ণসংখ্যা হয় )। আইএমএইচও বোঝার জন্য কোডকে কোডকে সহজ করে তোলে এমন কিছুই বাদ দেয় না। উত্তর করার জন্য ধন্যবাদ!
জোহান্দো

1
@johndodo। উপস। সম্পাদনা করা হয়েছে।
speckledcarp

7
কেন this.state = { width: window.innerWidth, height: window.innerHeight };শুরু করবেন না ?
গার্বাস

1
উইন্ডোর পুনরায় আকারের ইভেন্টটি লক্ষ্যবস্তু করতে কলব্যাক ব্যবহার করুন এবং তারপরে কলব্যাকের অভ্যন্তরে গ্লোবাল উইন্ডো অবজেক্টটিকে পুনরায় লক্ষ্যবস্তু করা সম্ভবত সেরা ধারণা নয়। কর্মক্ষমতা, পাঠযোগ্যতা এবং কনভেনশন স্বার্থে, আমি প্রদত্ত ইভেন্টের মানগুলি ব্যবহার করতে এটি আপডেট করতে যাচ্ছি।
গোরডিফেক্স 30'18

174

হুক ব্যবহার করে (প্রতিক্রিয়া 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 কোনও ফাংশন নয়, এটি একটি সম্পত্তি
জাইরো

2
দেখে মনে হচ্ছে কেভিন ড্যানিকোভস্কি উত্তর সম্পাদনা করেছেন এবং কোনওভাবে সেই পরিবর্তন অনুমোদিত হয়েছে। এটি এখন স্থির।
QoP

3
@ উপাদানটি আনমাউন্ট করার পরে এটি ইভেন্ট শ্রোতাদের সরান। এটিকে cleanupফাংশন বলা হয় , আপনি এটি সম্পর্কে এখানে
QoP

1
এসএসআর (নেক্সটজেএস) এর সাথে একই পন্থা পেতে কোনও ধারণা?
রোডেভ

1
নেক্সটজেএস-এ @roadev, আপনি reqপ্রপ চালু আছে কিনা তাও পরীক্ষা করতে পারেন getInitialProps। যদি এটি হয় তবে এটি সার্ভারে চলছে, তবে আপনার উইন্ডো ভেরিয়েবলগুলি নেই।
giovannipds

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 as হিসাবে উপলব্ধ


13
যদি ব্রাউজার উইন্ডোতে আয়তন পরিবর্তিত এই সমাধান আপডেট করা হয় না
speckledcarp

1
এফওয়াইআই, একটি উপাদান মাউন্টের পরে রাষ্ট্র আপডেট করে দ্বিতীয় রেন্ডার কল () কল ট্রিগার করবে এবং সম্পত্তি / লেআউট থ্র্যাশিংয়ের দিকে নিয়ে যেতে পারে। github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/…
হাকুর ক্রিস্টিনসন

1
@ হাকুরক্রিস্টিনসন কীভাবে এটিকে কাটিয়ে উঠবেন?
রিচার্ড

1
@ জাবরান সাeedদ কেন মাউন্টে আপডেট করার পরিবর্তে কেবল এগিয়ে গিয়ে কনস্ট্রাক্টরের উচ্চতা নির্ধারণ করবেন না? আপনি ভালো এটি মান ডিফল্ট করতে পারেন বিবেচনা সাজসরঞ্জাম নিতে প্রয়োজন: height: window.innerHeight || props.height। এটি কেবল কোডটি সহজ করবে না তবে অপ্রয়োজনীয় রাষ্ট্র পরিবর্তনগুলিও সরিয়ে ফেলবে।
জননিকিউ

componentWillMountআর সুপারিশ করা হয় না, reactjs.org/docs/react-component.html#unsafe_componentwillmount
হলবার্ড

25

আমি শুধু সম্পাদনা করেছেন QoP এর বর্তমান উত্তর সমর্থন করার জন্য SSR এবং সঙ্গে এটি ব্যবহার Next.js (প্রতিক্রিয়া 16.8.0+):

/ হুক্স / ইউজ উইন্ডোডাইমেনশনস.জেএস :

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

/ আপনাররকম্পোনেন্ট.জেএস :

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

দুর্দান্ত সমাধান।
জেরেমি ই

15

@ স্পেকলেডকার্পের উত্তর দুর্দান্ত, তবে একাধিক উপাদানগুলিতে আপনার এই যুক্তিটির প্রয়োজন হলে ক্লান্তিকর হতে পারে। এই যুক্তিটিকে পুনরায় ব্যবহার করা সহজ করার জন্য আপনি এটিটিকে এইচওসি (উচ্চতর অর্ডার উপাদান) হিসাবে রিফ্যাক্টর করতে পারেন ।

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

আপনার যদি অন্য কোনও ব্যবহারের প্রয়োজন হয় তবে আপনি এইচওসিগুলি "স্ট্যাক "ও করতে পারেন withRouter(withWindowDimensions(MyComponent))

সম্পাদনা করুন: আমি আজকাল একটি প্রতিক্রিয়া হুক নিয়ে যাব ( উপরে উদাহরণস্বরূপ এখানে ), কারণ তারা এইচওসি এবং ক্লাসগুলির সাথে কিছু উন্নত সমস্যাগুলি সমাধান করে


1
ভাল কাজ @ জেমস
মনিশ শর্মা

8

আমি কেবল প্রতিক্রিয়া এবং স্ক্রোলিং ইভেন্ট / অবস্থানগুলি নিয়ে কিছু জিনিস বের করার জন্য কিছুটা গুরুতর সময় ব্যয় করেছি - সুতরাং যারা এখনও খুঁজছেন তাদের জন্য আমি যা পেয়েছি তা এখানে:

ভিউপোর্টের উচ্চতা উইন্ডো। (বর্তমান ভিউপোর্ট উচ্চতা)

উইন্ডো.ডোকমেন্ট.বিডি.অফসেটহাইট ব্যবহার করে পুরো ডকুমেন্টের (বডি) উচ্চতা পাওয়া যাবে।

আপনি যদি নথির উচ্চতা সন্ধান করার চেষ্টা করছেন এবং আপনি কখন নীচে আঘাত করেছেন তা যদি জানেন - আমি এখানে যা এলাম তা এখানে:

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

রক্ষে! আশা করি এটি কাউকে সাহায্য করবে!


2

@ স্পেকলেডকার্প এবং @ জেমসেলের উত্তর দুটি উজ্জ্বল। আমার ক্ষেত্রে যাইহোক, আমার এমন একটি উপাদানের প্রয়োজন ছিল যার উচ্চতা পুরো উইন্ডো উচ্চতা বাড়িয়ে দিতে পারে, রেন্ডার সময় শর্তাধীন .... তবে এইচওসি কল করা render()পুরো সাবট্রিকে পুনরায় রেন্ডার করে। BAAAD।

এছাড়াও, আমি প্রপস হিসাবে মানগুলি পেতে আগ্রহী নই তবে কেবল এমন পিতামাতাকে চেয়েছিলাম 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

2
// 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
স্ট্যাক ওভারফ্লোতে আপনাকে স্বাগতম। কোনও ব্যাখ্যা ছাড়াই কোড ডাম্প খুব কমই সহায়ক। স্ট্যাক ওভারফ্লো শিখার বিষয়ে, অন্ধভাবে অনুলিপি করে অনুলিপি করার জন্য স্নিপেট সরবরাহ করে না। দয়া করে আপনার প্রশ্নটি সম্পাদনা করুন এবং ওপি কী সরবরাহ করেছে তার থেকে এটি কীভাবে ভাল কাজ করে তা ব্যাখ্যা করুন।
ক্রিস

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);
}
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.