React.js তে একটি উপাদান onScrol এর স্টাইল আপডেট করুন


133

আমি প্রতিক্রিয়াতে একটি উপাদান তৈরি করেছি যা প্যারালাক্স প্রভাব তৈরি করতে উইন্ডো স্ক্রোলটিতে তার নিজস্ব স্টাইল আপডেট করার কথা।

উপাদান renderপদ্ধতিটি এর মতো দেখাচ্ছে:

  function() {
    let style = { transform: 'translateY(0px)' };

    window.addEventListener('scroll', (event) => {
      let scrollTop = event.srcElement.body.scrollTop,
          itemTranslate = Math.min(0, scrollTop/3 - 60);

      style.transform = 'translateY(' + itemTranslate + 'px)');
    });

    return (
      <div style={style}></div>
    );
  }

এটি কাজ করে না কারণ প্রতিক্রিয়াটি জানে না যে উপাদানটি পরিবর্তিত হয়েছে, এবং সেইজন্য উপাদানটি পুনরায় সরবরাহ করা হয়নি।

আমি itemTranslateউপাদানটির স্থিতির মানটি সংরক্ষণ করার চেষ্টা করেছি এবং setStateস্ক্রোল কলব্যাকে কল করছি । যাইহোক, এটি স্ক্রোলিংটিকে ব্যবহারযোগ্য করে তুলছে না কারণ এটি মারাত্মকভাবে ধীর।

এটি কিভাবে করবেন সে সম্পর্কে কোনও পরামর্শ?


9
রেন্ডার পদ্ধতির অভ্যন্তরে কোনও বাহ্যিক ইভেন্ট হ্যান্ডলারকে কখনই বাঁধবেন না। রেন্ডারিং পদ্ধতিগুলি (এবং renderএকই থ্রেড থেকে আপনি যে কোনও কাস্টম পদ্ধতি কল করেন ) কেবলমাত্র রিঅ্যাক্টে আসল ডিওএম রেন্ডারিং / আপডেট করার ক্ষেত্রে যুক্তিযুক্ত হতে হবে। পরিবর্তে, নীচে @ অস্টিনগ্রেকোর দেখানো অনুসারে, আপনার ইভেন্ট বন্ডিং তৈরি এবং মুছে ফেলার জন্য আপনার প্রদত্ত প্রতিক্রিয়া জীবনচক্র পদ্ধতিগুলি ব্যবহার করা উচিত। এটি এটি উপাদানটির অভ্যন্তরে স্ব-অন্তর্ভুক্ত করে এবং ইভেন্ট বন্ডিং সরিয়ে ফেলা নিশ্চিত করে / যদি কখন যে উপাদানটি ব্যবহার করে এমন উপাদানটি আনমাউন্ট হয় তা নিশ্চিত করে কোনও ফাঁস নিশ্চিত করে।
মাইক চালক

উত্তর:


232

আপনার শ্রোতাদের বেঁধে রাখা উচিত componentDidMount, এইভাবে এটি একবারে তৈরি হয়েছিল। আপনার স্টাইলটি স্টেটে রাখতে সক্ষম হওয়া উচিত, শ্রোতা সম্ভবত পারফরম্যান্স সমস্যার কারণ ছিলেন।

এটার মতো কিছু:

componentDidMount: function() {
    window.addEventListener('scroll', this.handleScroll);
},

componentWillUnmount: function() {
    window.removeEventListener('scroll', this.handleScroll);
},

handleScroll: function(event) {
    let scrollTop = event.srcElement.body.scrollTop,
        itemTranslate = Math.min(0, scrollTop/3 - 60);

    this.setState({
      transform: itemTranslate
    });
},

26
আমি দেখতে পেলাম যে অ্যানিমেশনের জন্য স্ক্রোল ইভেন্টের ভিতরে সেটস্টেট'ই চপ্পটি। রেফ ব্যবহার করে আমাকে নিজেই উপাদানগুলির স্টাইলটি সেট করতে হয়েছিল।
রায়ান রোহ

1
হ্যান্ডেলস্ক্রোলের ভিতরে "এটি" কী নির্দেশ করবে? আমার ক্ষেত্রে এটি "উইন্ডো" উপাদান নয়। আমি পরামিতি হিসাবে উপাদানটি শেষ করে শেষ করি
yuji

10
@ আইজি আপনি কনস্ট্রাক্টরে আবদ্ধ হয়ে উপাদানটি পাস করার প্রয়োজন এড়াতে পারেন: এটি উইন্ডোর পরিবর্তে উপাদানটির this.handleScroll = this.handleScroll.bind(this)সাথে আবদ্ধ করবে handleScroll
ম্যাট পার্লিলা

1
নোট করুন যে ফায়ারফক্সে srcElement উপলব্ধ নয়।
পাউলিন ট্রোগন

2
আমার পক্ষে কাজ করেনি, তবে কী স্ক্রোলটপ সেট করছেevent.target.scrollingElement.scrollTop
জর্জ

31

আপনি onScrollপ্রতিক্রিয়া উপাদানটিতে ইভেন্টটিতে কোনও ফাংশনটি পাস করতে পারবেন : https://facebook.github.io/react/docs/events.html#ui-events

<ScrollableComponent
 onScroll={this.handleScroll}
/>

অনুরূপ অন্য একটি উত্তর: https://stackoverflow.com/a/36207913/1255973


5
উইন্ডো উপাদান @ অস্টিনগ্রেকোতে ম্যানুয়ালি ইভেন্ট শ্রোতাদের যুক্ত করে এই পদ্ধতিতে কোনও সুবিধা / অসুবিধা আছে কি?
ডেনিস

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

4
এটি লক্ষণীয় যে এটি নিজেই উপাদানটির সাথে একটি স্ক্রোল হ্যান্ডলার সংযুক্ত করে, উইন্ডোতে নয়, যা একটি খুব আলাদা জিনিস। @ ডেনিস অনস্ক্রোলের সুবিধা হ'ল এটি আরও ক্রস-ব্রাউজার এবং আরও পারফরম্যান্ট forma আপনি যদি এটি ব্যবহার করতে পারেন তবে আপনার সম্ভবত হওয়া উচিত, তবে এটি ওপি
বিউ

20

একটি প্রতিক্রিয়াশীল নাবার তৈরি করার জন্য আমার সমাধান (অবস্থান: 'আপেক্ষিক' যখন স্ক্রোল করার সময় নয় এবং পৃষ্ঠার শীর্ষে না থাকলে স্ক্রল করার সময় স্থির করা হয়েছে)

componentDidMount() {
    window.addEventListener('scroll', this.handleScroll);
}

componentWillUnmount() {
    window.removeEventListener('scroll', this.handleScroll);
}
handleScroll(event) {
    if (window.scrollY === 0 && this.state.scrolling === true) {
        this.setState({scrolling: false});
    }
    else if (window.scrollY !== 0 && this.state.scrolling !== true) {
        this.setState({scrolling: true});
    }
}
    <Navbar
            style={{color: '#06DCD6', borderWidth: 0, position: this.state.scrolling ? 'fixed' : 'relative', top: 0, width: '100vw', zIndex: 1}}
        >

আমার জন্য কোনও পারফরম্যান্স সমস্যা নেই।


আপনি একটি জাল শিরোনামও ব্যবহার করতে পারেন যা মূলত কেবল একটি স্থানধারক। সুতরাং আপনি আপনার স্থির শিরোনাম পেয়েছেন এবং এর নীচে আপনি আপনার স্থানধারক জাল শিরোনাম পজিশনের সাথে পেয়েছেন: আপেক্ষিক।
রবিন_২২

কোনও পারফরম্যান্সের সমস্যা নেই কারণ এটি প্রশ্নে প্যারাল্যাক্স চ্যালেঞ্জকে সম্বোধন করে না।
জুয়ানিটোগান

19

অস্ট্রিনের উত্তরটি ব্যবহার করার সময় যারা লগি আচরণ / পারফরম্যান্সের বিষয়গুলি লক্ষ্য করেছেন এবং মন্তব্যগুলিতে উল্লিখিত রেফ ব্যবহার করে একটি উদাহরণ চান তা এখানে সহায়তার জন্য, এখানে একটি উদাহরণ আমি স্ক্রোল আপ / ডাউন আইকনের জন্য ক্লাস টগল করার জন্য ব্যবহার করছিলাম:

রেন্ডার পদ্ধতিতে:

<i ref={(ref) => this.scrollIcon = ref} className="fa fa-2x fa-chevron-down"></i>

হ্যান্ডলার পদ্ধতিতে:

if (this.scrollIcon !== null) {
  if(($(document).scrollTop() + $(window).height() / 2) > ($('body').height() / 2)){
    $(this.scrollIcon).attr('class', 'fa fa-2x fa-chevron-up');
  }else{
    $(this.scrollIcon).attr('class', 'fa fa-2x fa-chevron-down');
  }
}

এবং আপনার হ্যান্ডলারগুলিকে অস্টিনের উল্লিখিতভাবে যুক্ত করুন / সরান:

componentDidMount(){
  window.addEventListener('scroll', this.handleScroll);
},
componentWillUnmount(){
  window.removeEventListener('scroll', this.handleScroll);
},

উপর ডক্স refs


4
তুমি আমার দিন বাঁচিয়েছ! আপডেট করার জন্য, আসলে এই মুহুর্তে আপনার ক্লাসের নামটি সংশোধন করতে jquery ব্যবহার করার দরকার নেই, কারণ এটি ইতিমধ্যে একটি নেটিভ ডোম উপাদান। সুতরাং আপনি সহজভাবে করতে পারে this.scrollIcon.className = whatever-you-want
দক্ষিণ

2
এই সমাধানটি অ্যাক্যাপসুলেশনটির প্রতিক্রিয়া ভেঙে ফেলেছে যদিও আমি এখনও লগি আচরণ ব্যতিরেকে কোনও উপায় সম্পর্কে নিশ্চিত নই - সম্ভবত একটি ঘোরাঘুরি করা স্ক্রোল ইভেন্ট (সম্ভবত 200-250 এমএসে) এখানে সমাধান হতে পারে
জর্দান

নোপ স্ক্রোলিং ইভেন্টটি কেবলমাত্র স্ক্রোলিংকে মসৃণ করতে সহায়তা করে (অ-ব্লকিং অর্থে), তবে ডিওমে আবেদনের জন্য আপডেটগুলি জানার জন্য এটি 500 সেকেন্ডে লাগে: /
জর্ডান

আমি এই সমাধানটিও ব্যবহার করেছি, +1। আমি সম্মত হলাম আপনার jQuery দরকার নেই: কেবল ব্যবহার করুন classNameবা classList। এছাড়াও, আমার দরকার নেইwindow.addEventListener() : আমি কেবল প্রতিক্রিয়া ব্যবহার করেছি onScrollএবং যতক্ষণ না আপনি প্রপস / রাষ্ট্র আপডেট করবেন না ততক্ষণ তা তত দ্রুত!
বেনিয়ামিন

13

আমি দেখতে পেয়েছি যে আমি যদি সত্যরূপে সত্য পাস না করি তবে আমি ইভেন্ট শ্রোতার সাথে সাফল্যের সাথে যোগ করতে পারি না:

componentDidMount = () => {
    window.addEventListener('scroll', this.handleScroll, true);
},

ইহা কাজ করছে. তবে কেন আপনি এই শ্রোতার কাছে সত্য বুলিয়ান পাস করতে হবে তা আপনি বুঝতে পারেন।
শাহ চৈতন্য

2
ডাব্লু 3 স্কুল থেকে: [ w3schools.com/jsref/met_docament_addeventlistener.asp] userCapture : ptionচ্ছিক । একটি বুলিয়ান মান যা ইভেন্টটি ক্যাপচারে বা বুদবুদ পর্যায়ে কার্যকর করা উচিত তা নির্দিষ্ট করে। সম্ভাব্য মান: সত্য - ইভেন্ট হ্যান্ডলারটি ক্যাপচারিং পর্বে মিথ্যা-ডিফল্টে কার্যকর করা হয়। ইভেন্ট হ্যান্ডলার বুদবুদ পর্বে কার্যকর করা হয়
জিন-মেরি ডালমাসো

12

ব্যবহার একটি উদাহরণ classNames , প্রতিক্রিয়া আঙ্গুলসমূহ useEffect , useState এবং স্টাইল-jsx :

import classNames from 'classnames'
import { useEffect, useState } from 'react'

const Header = _ => {
  const [ scrolled, setScrolled ] = useState()
  const classes = classNames('header', {
    scrolled: scrolled,
  })
  useEffect(_ => {
    const handleScroll = _ => { 
      if (window.pageYOffset > 1) {
        setScrolled(true)
      } else {
        setScrolled(false)
      }
    }
    window.addEventListener('scroll', handleScroll)
    return _ => {
      window.removeEventListener('scroll', handleScroll)
    }
  }, [])
  return (
    <header className={classes}>
      <h1>Your website</h1>
      <style jsx>{`
        .header {
          transition: background-color .2s;
        }
        .header.scrolled {
          background-color: rgba(0, 0, 0, .1);
        }
      `}</style>
    </header>
  )
}
export default Header

1
নোট করুন যেহেতু এই ইউজএফেক্টের একটি দ্বিতীয় যুক্তি নেই, এটি প্রতিবার শিরোনামের শিরোনামে চলবে।
জর্দান

2
@ জর্ডান আপনি ঠিক বলেছেন! আমার ভুল এখানে লিখতে। আমি উত্তরটি সম্পাদনা করব। আপনাকে অনেক ধন্যবাদ.
জিয়োভানিপডস

8

হুকস সহ

import React, { useEffect, useState } from 'react';

function MyApp () {

  const [offset, setOffset] = useState(0);

  useEffect(() => {
    window.onscroll = () => {
      setOffset(window.pageYOffset)
    }
  }, []);

  console.log(offset); 
};

ঠিক আমার যা প্রয়োজন ছিল। ধন্যবাদ!
aabbccsmith

এটি এখন পর্যন্ত সবচেয়ে কার্যকর এবং মার্জিত উত্তর। এর জন্য ধন্যবাদ.
চিগোজি ওরন্টা

এটি আরও মনোযোগ প্রয়োজন, নিখুঁত।
অ্যান্ডারস কিটসন

6

UseEffect ব্যবহার করে ফাংশন উপাদান উদাহরণ:

বিঃদ্রঃ : ইউজএফেক্টে "ক্লিন আপ" ফাংশনটি ফিরিয়ে আপনার ইভেন্ট শ্রোতাদের অপসারণ করতে হবে। আপনি যদি না করেন, প্রতিবার উপাদানটি আপডেট হলে আপনার একটি অতিরিক্ত উইন্ডো স্ক্রোল শ্রোতা পাবেন।

import React, { useState, useEffect } from "react"

const ScrollingElement = () => {
  const [scrollY, setScrollY] = useState(0);

  function logit() {
    setScrollY(window.pageYOffset);
  }

  useEffect(() => {
    function watchScroll() {
      window.addEventListener("scroll", logit);
    }
    watchScroll();
    // Remove listener (like componentWillUnmount)
    return () => {
      window.removeEventListener("scroll", logit);
    };
  }, []);

  return (
    <div className="App">
      <div className="fixed-center">Scroll position: {scrollY}px</div>
    </div>
  );
}

নোট করুন যেহেতু এই ইউজএফেক্টের একটি দ্বিতীয় যুক্তি নেই, এটি প্রতি একক সময় উপাদানটি রেন্ডার করবে।
জর্ডান

ভাল যুক্তি. আমরা কি ব্যবহারের কলটিতে একটি ফাঁকা অ্যারে যুক্ত করব?
রিচার্ড

আমি এটাই করব :)
জর্ডান

5

আপনার যদি আগ্রহী এমন কোনও শিশু উপাদান যা স্ক্রল করছে তবে তা এই উদাহরণটি সহায়ক হতে পারে: https://codepen.io/JohnReynolds57/pen/NLNOyO?editors=0011

class ScrollAwareDiv extends React.Component {
  constructor(props) {
    super(props)
    this.myRef = React.createRef()
    this.state = {scrollTop: 0}
  }

  onScroll = () => {
     const scrollTop = this.myRef.current.scrollTop
     console.log(`myRef.scrollTop: ${scrollTop}`)
     this.setState({
        scrollTop: scrollTop
     })
  }

  render() {
    const {
      scrollTop
    } = this.state
    return (
      <div
         ref={this.myRef}
         onScroll={this.onScroll}
         style={{
           border: '1px solid black',
           width: '600px',
           height: '100px',
           overflow: 'scroll',
         }} >
        <p>This demonstrates how to get the scrollTop position within a scrollable 
           react component.</p>
        <p>ScrollTop is {scrollTop}</p>
     </div>
    )
  }
}

1

সিএসএস ভেরিয়েবলগুলি ব্যবহার করে এবং সংশোধন করার মাধ্যমে আমি সমস্যার সমাধান করেছি। এইভাবে আমাকে কম্পোনেন্টের স্থিতিটি পরিবর্তন করতে হবে না যা পারফরম্যান্সের সমস্যাগুলির জন্য।

index.css

:root {
  --navbar-background-color: rgba(95,108,255,1);
}

Navbar.jsx

import React, { Component } from 'react';
import styles from './Navbar.module.css';

class Navbar extends Component {

    documentStyle = document.documentElement.style;
    initalNavbarBackgroundColor = 'rgba(95, 108, 255, 1)';
    scrolledNavbarBackgroundColor = 'rgba(95, 108, 255, .7)';

    handleScroll = () => {
        if (window.scrollY === 0) {
            this.documentStyle.setProperty('--navbar-background-color', this.initalNavbarBackgroundColor);
        } else {
            this.documentStyle.setProperty('--navbar-background-color', this.scrolledNavbarBackgroundColor);
        }
    }

    componentDidMount() {
        window.addEventListener('scroll', this.handleScroll);
    }

    componentWillUnmount() {
        window.removeEventListener('scroll', this.handleScroll);
    }

    render () {
        return (
            <nav className={styles.Navbar}>
                <a href="/">Home</a>
                <a href="#about">About</a>
            </nav>
        );
    }
};

export default Navbar;

Navbar.module.css

.Navbar {
    background: var(--navbar-background-color);
}

1

আমার বাজি এখানে সমাধানের জন্য নতুন হুকের সাথে ফাংশন উপাদানগুলি ব্যবহার করছে, তবে useEffectপূর্ববর্তী উত্তরের মতো ব্যবহার করার পরিবর্তে , আমি মনে করি সঠিক বিকল্পটি useLayoutEffectএকটি গুরুত্বপূর্ণ কারণে হবে:

স্বাক্ষরটি ব্যবহারের জন্য অভিন্ন, তবে এটি সমস্ত ডিওএম মিউটেশনের পরে সিঙ্ক্রোনজ ফায়ার করে।

এটি প্রতিক্রিয়া ডকুমেন্টেশনে পাওয়া যাবে । যদি আমরা ব্যবহার করিuseEffect পরিবর্তে এবং আমরা ইতিমধ্যে স্ক্রলযুক্ত পৃষ্ঠাটি পুনরায় লোড করি, স্ক্রোল করা মিথ্যা হবে এবং আমাদের শ্রেণি প্রয়োগ করা হবে না, যা একটি অযাচিত আচরণের কারণ হবে।

একটি উদাহরণ:

import React, { useState, useLayoutEffect } from "react"

const Mycomponent = (props) => {
  const [scrolled, setScrolled] = useState(false)

  useLayoutEffect(() => {
    const handleScroll = e => {
      setScrolled(window.scrollY > 0)
    }

    window.addEventListener("scroll", handleScroll)

    return () => {
      window.removeEventListener("scroll", handleScroll)
    }
  }, [])

  ...

  return (
    <div className={scrolled ? "myComponent--scrolled" : ""}>
       ...
    </div>
  )
}

সমস্যার সম্ভাব্য সমাধান হতে পারে https://codepen.io/dcalderon/pen/mdJzOYq

const Item = (props) => { 
  const [scrollY, setScrollY] = React.useState(0)

  React.useLayoutEffect(() => {
    const handleScroll = e => {
      setScrollY(window.scrollY)
    }

    window.addEventListener("scroll", handleScroll)

    return () => {
      window.removeEventListener("scroll", handleScroll)
    }
  }, [])

  return (
    <div class="item" style={{'--scrollY': `${Math.min(0, scrollY/3 - 60)}px`}}>
      Item
    </div>
  )
}

আমি সম্পর্কে কৌতূহল useLayoutEffect। আপনি যা উল্লেখ করেছেন তা দেখার চেষ্টা করছি।
জিওভান্নিপিডস

যদি আপনি কিছু মনে করেন না, আপনি দয়া করে এই ঘটনার কোনও রেপো + ভিজ্যুয়াল উদাহরণ সরবরাহ করতে পারেন? আপনি useEffectএখানে তুলনায় তুলনামূলকভাবে এখানে একটি সমস্যা হিসাবে উল্লেখ করেছেন তা পুনরুত্পাদন করতে পারিনি useLayoutEffect
জিওভানিপিডস

নিশ্চিত! https://github.com/calderon/uselayout-vs-uselayouteffect । গতকাল আমার সাথে একই রকম আচরণের সাথে ঘটেছিল। বিটিডাব্লু, আমি নবাগত একটি প্রতিক্রিয়া এবং সম্ভবত আমি সম্পূর্ণ ভুল: ডি: ডি
ক্যাল্ডারন

আসলে আমি অনেকবার চেষ্টা করে এসেছি, অনেকগুলি পুনরায় লোড করছি এবং কখনও কখনও এটি নীলের পরিবর্তে লাল রঙের শিরোনামে উপস্থিত হয়, যার অর্থ এটি .Header--scrolledকখনও কখনও বর্গ প্রয়োগ করা হয় , তবে 100% বার .Header--scrolledLayoutসঠিকভাবে প্রয়োগ করা হয়েছে ধন্যবাদ লেআউটএফেক্টের জন্য।
ক্যালডেরন


1

এখানে ব্যবহার করে অন্য উদাহরণ আঙ্গুলসমূহ fontAwesomeIcon এবং Kendo UI 'তে প্রতিক্রিয়া
[! [এখানে স্ক্রিনশট] [1]] [1]

import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';


const ScrollBackToTop = () => {
  const [show, handleShow] = useState(false);

  useEffect(() => {
    window.addEventListener('scroll', () => {
      if (window.scrollY > 1200) {
        handleShow(true);
      } else handleShow(false);
    });
    return () => {
      window.removeEventListener('scroll');
    };
  }, []);

  const backToTop = () => {
    window.scroll({ top: 0, behavior: 'smooth' });
  };

  return (
    <div>
      {show && (
      <div className="backToTop text-center">
        <button className="backToTop-btn k-button " onClick={() => backToTop()} >
          <div className="d-none d-xl-block mr-1">Top</div>
          <FontAwesomeIcon icon="chevron-up"/>
        </button>
      </div>
      )}
    </div>
  );
};

export default ScrollBackToTop;```


  [1]: https://i.stack.imgur.com/ZquHI.png

এটা সত্যিই দারুন. উইন্ডো.অনস্রোকল () ব্যবহার করে স্ক্রোলটিতে আমার নভবার স্টিকি স্টেটটি পরিবর্তন করার ক্ষেত্রে আমার ব্যবহারএফেক্টটিতে সমস্যা ছিল ... ... এই উত্তরের মাধ্যমে জানতে পেরেছি যে উইন্ডো.এডএভেন্টএলস্টনার () এবং উইন্ডো.রেভএভেন্টলিস্টনার () আমার স্টিকি নিয়ন্ত্রণের জন্য সঠিক পদ্ধতি একটি কার্যকরী উপাদান সহ নববার ... ধন্যবাদ!
মাইকেল

1

প্রতিক্রিয়া হুক্স সঙ্গে একটি উত্তর জন্য আপডেট

এগুলি দুটি হুক - একটি দিকের জন্য (উপরে / নিচে / কিছুই নয়) এবং একটি আসল অবস্থানের জন্য

এটি ব্যবহার করুন:

useScrollPosition(position => {
    console.log(position)
  })

useScrollDirection(direction => {
    console.log(direction)
  })

হুকগুলি এখানে:

import { useState, useEffect } from "react"

export const SCROLL_DIRECTION_DOWN = "SCROLL_DIRECTION_DOWN"
export const SCROLL_DIRECTION_UP = "SCROLL_DIRECTION_UP"
export const SCROLL_DIRECTION_NONE = "SCROLL_DIRECTION_NONE"

export const useScrollDirection = callback => {
  const [lastYPosition, setLastYPosition] = useState(window.pageYOffset)
  const [timer, setTimer] = useState(null)

  const handleScroll = () => {
    if (timer !== null) {
      clearTimeout(timer)
    }
    setTimer(
      setTimeout(function () {
        callback(SCROLL_DIRECTION_NONE)
      }, 150)
    )
    if (window.pageYOffset === lastYPosition) return SCROLL_DIRECTION_NONE

    const direction = (() => {
      return lastYPosition < window.pageYOffset
        ? SCROLL_DIRECTION_DOWN
        : SCROLL_DIRECTION_UP
    })()

    callback(direction)
    setLastYPosition(window.pageYOffset)
  }

  useEffect(() => {
    window.addEventListener("scroll", handleScroll)
    return () => window.removeEventListener("scroll", handleScroll)
  })
}

export const useScrollPosition = callback => {
  const handleScroll = () => {
    callback(window.pageYOffset)
  }

  useEffect(() => {
    window.addEventListener("scroll", handleScroll)
    return () => window.removeEventListener("scroll", handleScroll)
  })
}

0

@ অস্টিনের উত্তরটি প্রসারিত this.handleScroll = this.handleScroll.bind(this)করতে আপনার কনস্ট্রাক্টরের সাথে যুক্ত করা উচিত :

constructor(props){
    this.handleScroll = this.handleScroll.bind(this)
}
componentDidMount: function() {
    window.addEventListener('scroll', this.handleScroll);
},

componentWillUnmount: function() {
    window.removeEventListener('scroll', this.handleScroll);
},

handleScroll: function(event) {
    let scrollTop = event.srcElement.body.scrollTop,
        itemTranslate = Math.min(0, scrollTop/3 - 60);

    this.setState({
      transform: itemTranslate
    });
},
...

এই দেয় handleScroll()ইভেন্ট শ্রোতার কাছ থেকে ডাকলে এটি যথাযথ সুযোগটিতে অ্যাক্সেস ।

এছাড়াও আপনি সচেতন .bind(this)হন addEventListenerবা removeEventListenerপদ্ধতিগুলিতে আপনি এটি করতে পারবেন না কারণ তারা প্রত্যেকে বিভিন্ন ফাংশনে উল্লেখ করে এবং উপাদানটি আনমাউন্ট করার পরে ইভেন্টটি সরানো হবে না।

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