在打字稿 React 中使用带有事件参数的闭包

问题描述 投票:0回答:2

我正在尝试使用 typescript React 的闭包来实现去抖动功能。 问题在于,每次我尝试传递事件参数时,它似乎都会对该函数进行新的引用。所以我认为这与传递和执行有关

_handleScroll
...有人可以帮助我吗?

这行不通

  const _handleScroll = (e: UIEvent<HTMLElement>): (() => void) => {
    e.stopPropagation();
    let prev = Date.now();
    const debounce = 500; // 500ms
    let counter = 0;

    return () => {
      const now = Date.now();
      if (prev - now > debounce) {
        prev = now;
        setScrollHeight(e.currentTarget.scrollTop);
      }
      ++counter;
      console.log("@@@", { now, prev, counter }); // result: counter: 1, 1, 1,...
    };
  };

...

    <div
      className="h-full overflow-y-auto"
      onScroll={(e) => _handleScroll(e)()}
    >

...

但这有效


  const _handleScroll = (): (() => void) => {
    // e.stopPropagation();
    let prev = Date.now();
    const debounce = 500; // 500ms
    let counter = 0;

    return () => {
      const now = Date.now();
      if (prev - now > debounce) {
        prev = now;
        // setScrollHeight(e.currentTarget.scrollTop);
      }
      ++counter;
      console.log("@@@", { now, prev, counter }); // result: counter: 1, 2, 3,...
    };
  };
...

<div className="h-full overflow-y-auto" onScroll={_handleScroll()}>

...
javascript reactjs typescript closures
2个回答
0
投票

在传递像 onScroll={_handleScroll()} 这样的句柄滚动时提供的第二个代码块中,您正在传递该函数的返回值。 但在第一块代码中,您传递的 onScroll={_handleScroll} 实际上是传递该函数的 reference 。并且 每次组件重新渲染时,传递给 div 的引用都会改变 如果你想阻止使用 useCallback hook,它与 useEffect 类似,你将函数包装在其中并将依赖项传递到 [] 中,它基本上会缓存你的函数引用,并且仅在依赖项更改时才更改它 希望这有帮助


0
投票

我认为如果我了解您想要什么,将会很有帮助。

useRef 用于避免重新渲染。

let prev = useRef<number>();
  let height = useRef<number>(0);
  const _handleScroll = () => {
    const now = Date.now();
    const debounce = 500; // 500ms

    if (!prev.current) {
      ++height.current;
      prev.current = Date.now();
      setScrollHeight(e.currentTarget.scrollTop);
    }
    if (!!prev.current && now - prev.current > debounce) {
      prev.current = Date.now();
      setScrollHeight(e.currentTarget.scrollTop);
      ++height.current;
    }
  };

<div className="h-full overflow-y-auto" onScroll={_handleScroll}>

_handleScroll 每次滚动都会被激活,但状态更新 500ms。

© www.soinside.com 2019 - 2024. All rights reserved.