Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to describe type scroll events?

I added listener on scroll, and tried to use event. How can I describe type instead of any ?

React 16.8.6 Tpescript 3.4

const Component: FC<IProps> = ({ children, scrollOffset, getScrollTop, videoListScrollUpdate }) => {
    const scroller = useRef<HTMLDivElement>(null)

    useEffect(() => {
        if (scrollOffset && scroller.current) {
            scroller.current.scrollTop = scrollOffset
            return
        }
        if (getScrollTop && scroller.current) {
            scroller.current.addEventListener('scroll', (e: any) => getScrollTop(e.target.scrollTop))
        }
    }, [])

}
like image 925
Arseniy Avatar asked May 16 '19 08:05

Arseniy


2 Answers

You can use (e: React.UIEvent<HTMLElement>). Described under the UIEvent from SyntheticEvents.

That said, I would advise against using useRef within a useEffect. It's tricky to determine whether useEffect was re-called and scroller.current wasn't null (even console.log can be misleading about it).

However I would suggest to instead use the inbuilt onScroll prop on the component you are attaching the ref to, and give it a callback to handle the scroll. That way you don't need to attach it manually in the useEffect hook where you are forgetting to remove it on unmount(memory leak problems).


interface IProps {
  children: React.ReactNode;
  getScrollTop: (scrollTop: number) => whatever;
  // Your other Props
}

const ScrollComponent: React.FC<IProps> = ({
  children,
  getScrollTop,
  // Your other props
}): JSX.Element => {
  const handleScroll = (e: React.UIEvent<HTMLElement>): void => {
    e.stopPropagation() // Handy if you want to prevent event bubbling to scrollable parent
    console.log({
      event: e,
      target: e.target, // Note 1* scrollTop is undefined on e.target
      currentTarget: e.currentTarget,
      scrollTop: e.currentTarget.scrollTop,
    });

    const { scrollTop } = e.currentTarget;
    getScrollTop(scrollTop);
  };

  return (
  <div
    // I am assuming you were referencing your scroller as follows.
    // ref={scroller}
    onScroll={handleScroll} // Use the onScroll prop instead.
  >
    {children}
  </div>
  );
};

Note *1: scrollTop wont be available on e.target.scrollTop, much as you can see in in the console.log, but on e.currentTarget.scrollTop, since currentTarget calls the element on which the event handler is attached to.

like image 169
iamcastelli Avatar answered Nov 16 '22 01:11

iamcastelli


This worked for me -

//register the scroll event listener callback function
useEffect(() => {
    window.addEventListener('scroll', onScroll)
    return () => {
      window.removeEventListener('scroll', onScroll)
    }
  })
// scroll event callback function
  const onScroll = (e: Event) => {
    const window = e.currentTarget as Window
    //... rest of you function
  }

Make sure to include dom lib in tsconfig.json

"compilerOptions": {
      "target": "es5",
      "lib": [
        "dom",
        "dom.iterable",
        ...
      ],
like image 44
Manju Prabhu Avatar answered Nov 16 '22 01:11

Manju Prabhu