Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to add Event in React Functional Component

Tags:

reactjs

I have a question about React functional components, specifically about functions in functional components. For instance:

import React, { useEffect } from 'react';

const Component = (props) => {  
  useEffect(() => {
    window.addEventListener('scroll', handleScroll);
  });
  useEffect(() => {
    return () => {
      window.removeEventListener('scroll', handleScroll);
    };
  }, []);

  function handleScroll() {
    let scrollTop = window.scrollY;
  }


  return ()
}
like image 255
Armen Nersisyan Avatar asked Nov 13 '19 06:11

Armen Nersisyan


2 Answers

This is just a quick demo on how to use useEffect to subscribe to event, useRef to create element ref for event listener, and useState to store the event results.

Please note that this is for the sake of demonstration purpose only. Calling setState in every tick of scroll event callback is NOT ideal.

import React, { useState, useEffect, useRef } from "react";
import ReactDOM from "react-dom";

import "./styles.css";

const App = () => {
  // set default value
  const [scrollTop, setScrollTop] = useState(document.body.scrollTop);

  // create element ref
  const innerRef = useRef(null);

  useEffect(() => {
    const div = innerRef.current;
    // subscribe event
    div.addEventListener("scroll", handleOnScroll);
    return () => {
      // unsubscribe event
      div.removeEventListener("scroll", handleOnScroll);
    };
  }, []);

  const handleOnScroll = (e) => {
    // NOTE: This is for the sake of demonstration purpose only.
    // Doing this will greatly affect performance.
    setScrollTop(e.target.scrollTop);
  }

  return (
    <>
      {`ScrollTop: ${scrollTop}`}
      <div
        style={{
          overflow: 'auto',
          width: 500,
          height: 500,
          border: '1px solid black',
        }}
        ref={innerRef}
      >
        <div style={{ height: 1500, width: 1500 }}>
          Scroll Me
        </div>
      </div>
    </>
  )
}

const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);

Here is a working demo in code sandbox: https://codesandbox.io/s/react-functional-component-event-listener-demo-fmerz?fontsize=14

like image 80
junwen-k Avatar answered Oct 10 '22 13:10

junwen-k


You should add and remove the eventlistener in the same useEffect-call. For instance:

import React, { useEffect } from 'react';

const Component = (props) => {

  useEffect(() => {
    function handleScroll() {
      const scrollTop = window.scrollY;
      console.log(scrollTop);
    }

    window.addEventListener('scroll', handleScroll);

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

  return (
    <div />
  );
}
like image 41
Damien Flury Avatar answered Oct 10 '22 14:10

Damien Flury