Lodash 油门不节流?

Lodash throttle not throttling?

我第一次尝试使用 lodash 节流阀。

我知道必须在 useCallback 内部应用油门,否则每次重新渲染都会调用它(在我的例子中,用户搜索的每次新按键)。

我的代码是有效的,逻辑似乎是有道理的 - 但没有应用节流阀,因此每次击键都会进行 api 调用。

关于我的逻辑在哪里失败的任何指示?

import {
    useEffect,
    useCallback
} from 'react';
import { throttle } from 'lodash';
import { getAllUsers } from '../../../api/api';
import { USER_ROLE } from '../../../types/types'

interface IProps extends Omit<unknown, 'children'> {
    search?: string;
}

const DemoFanManagementTable = ({ search }: IProps): JSX.Element => {

    const getFans = (search?: string) => {
        console.log("getFans ran")
        const fans = getAllUsers({ search }, USER_ROLE.FAN);
        //logs a promise
        console.log("logging fans ", fans)
        return fans;
    }

    //throttledSearch is running every time search changes
    const throttledSearch = useCallback((search?: string) => {
        console.log("throttledSearch ran")
        return throttle(
            //throttle is not throttling, functions run every keystroke
            () => {
                getFans(search), 10000, { leading: true, trailing: true }
            }
        )
    }, [search])

    //useEffect is running every time search changes
    useEffect(() => {
        return throttledSearch(search)
    }, [search]);

    return (
        <div>
            {search}
        </div>
    );
};

export default DemoFanManagementTable;

这里有一些问题,首先你将空洞 throttle func 包装在一个匿名函数中,而不仅仅是第一个参数:

throttle(
  (search: string) => getFans(search),
  1000,
  { leading: true, trailing: true }
)

第二个 useCallback 不适合,因为每次调用它时,它都会返回一个新的节流函数。

第三,您已将 [search] 作为 useCallback 的依赖项传递,因此即使它按您的预期工作,每次 search 更改时它都会失效并且无论如何都无法工作。

更好的选择是 useMemo,因为它在渲染中保持相同的节流功能。

const throttledSearch = useMemo(
  () =>
    throttle(
      (search: string) => getFans(search),
      10000,
      { leading: true, trailing: true }
    ),
  []
);

useEffect(() => {
  return throttledSearch(search);
}, [search]);

由于 getFans 采用相同的搜索参数,您可以将其缩短为:

const throttledSearch = useMemo(() =>
  throttle(getFans, 10000, { leading: true, trailing: true }),
[]);