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 }),
[]);
我第一次尝试使用 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 }),
[]);