Giter Site home page Giter Site logo

Comments (4)

donavon avatar donavon commented on May 23, 2024 3

You can use a ref callback, something like this:

(see https://codesandbox.io/s/244jl7o300)

const arr = new Array(1000).fill().map((_, i) => i);

function App() {
  const [pos, setPos] = useState(0);
  const [element, setElement] = useState(null);

  useEventListener('scroll', ev => setPos(ev.target.scrollTop), element);

  return (
    <div>
      <div className="scroll" ref={el => setElement(el)}>
        {arr.map(i => (
          <div key={i}>{i}</div>
        ))}
      </div>
      <div>Scroll position: {pos}</div>
    </div>
  );
}

from use-event-listener.

VanOkazou avatar VanOkazou commented on May 23, 2024

Thank, it works !!

from use-event-listener.

hwride avatar hwride commented on May 23, 2024

Thanks for writing this library. I've found the binding and un-binding of event listeners to refs to be a bit non-intuitive to catch all the edge cases and have found this really useful.

I am trying to understand the logic behind all of this. If you get some time could you please let me know if the following sounds correct to you?

  1. You are using a callback ref here because you are only guaranteed to be notified about a ref being updated when using a callback ref, not a regular ref. From Hooks API Reference - useRef:

    Keep in mind that useRef doesn’t notify you when its content changes. Mutating the .current property doesn’t cause a re-render. If you want to run some code when React attaches or detaches a ref to a DOM node, you may want to use a callback ref instead.

    So if you had used a regular ref it could potentially have been updated and we might not have bound to the new element.

  2. When the ref changes you store that outcome in a state variable. This is done to ensure that a re-render is triggered when the ref changes. That re-render ensures that the second useEffect inside useEventListener triggers, which will un-bind the old event listener from the old element and bind a new event listener to the new element. And the un-binding all works correctly because the clean-up function returned from useEffect captures the original element value in a closure.

from use-event-listener.

stevejay avatar stevejay commented on May 23, 2024

Just for anyone landing here, the answer of using a ref callback to solve this issue can be made slightly more efficient:

  return (
    <div>
      <div className="scroll" ref={setElement}> // <-- no inline function here
        {arr.map((i) => (
          <div key={i}>{i}</div>
        ))}
      </div>
      <div>Scroll position: {pos}</div>
    </div>
  );

Codesandbox
This prevents an extra render when the component gets re-rendered.

from use-event-listener.

Related Issues (19)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.