What causes lodash debouncer "TypeError: Expected a function" error?
What causes lodash debouncer "TypeError: Expected a function" error?
我正在尝试在 React 函数组件中使用 lodash 的 debouncer 方法。当我尝试创建 debouncer-wrapped 回调时,我收到
TypeError: Expected a function
在 useCallback 语句处。我已尝试完成三个或四个示例,但其中 none 个可以在我现有的应用程序中使用。我最近的尝试是 here.
const [userQuery, setUserQuery] = useState("")
const [deb, setDeb] = useState("");
const updateQuery = () => {
setDeb(userQuery)
};
//const delayedQuery = useCallback(debounce(updateQuery, 500), []);
//const delayedQuery = useCallback(debounce(updateQuery, 500), [userQuery]);
const delayedQuery = useCallback(() => debounce(updateQuery, 500), [userQuery]);
const onChange = e => {
setUserQuery(e.target.value);
};
useEffect(() => {
delayedQuery();
// Cancel the debounce on useEffect cleanup.
return delayedQuery.cancel;
}, [userQuery, delayedQuery]);
代码在没有 debounce 包装器和 useEffect 中的相关 return 的情况下整体运行(当然没有任何 debouncing)。
评论中显示了其他变体,但都会导致相同的错误。
我对 React 还算满意,所以我对 React 的理解还有很多差距,这可能是问题所在。
编辑
该消息读给我听,好像 debounce 不被识别为函数。我没有收到有关尝试使用 import { debounce } from 'lodash/has';
或 import { debounce } from 'lodash/fp';
导入去抖动的问题的迹象
错误结果:
我假设提到的 TypeError
是在 useEffect
期间抛出的,因为您没有提供任何堆栈跟踪。
编辑 感谢@Ori Drori 的评论和建议:
将 delayedQuery
更改为以下内容:
const delayedQuery = useCallback(debounce(updateQuery, 500), []);
这样,您将拥有去抖动方法的记忆值,无论如何这将是一个回调,具有可用的 cancel
属性.
上一个答案(仅供参考):
那么您可以尝试将 useEffect
更改为以下内容:
useEffect(() => {
const query = delayedQuery();
query();
// Cancel the denounce on useEffect cleanup
return query.cancel;
}, [userQuery, delayedQuery]);
说明
您可以查看不同类型的方法和回调。我从头说起:
useCallback
只接受任何方法,return 是一个新方法,它将简单地调用提供的方法。它将匹配所提供方法的签名。
- 反过来,提供的回调是一个简单的箭头函数,return是一个
debounce
d 方法。
- 根据 lodash 文档,
debounce
d 方法可以立即调用,cancel
ed 或 flush
ed。
这导致我们在您的 useEffect
中出现以下内容:
delayedQuery
是一个回调。
- 您调用
delayedQuery()
,其中钩子调用箭头函数。
- 箭头函数调用
debounce
和 return 的值 — 去抖动的 updateQuery
!
- BUT: 此时,您的查询尚未被调用!此外,由于 只有 return 类型的回调 是去抖函数,所以没有 属性
delayedQuery.cancel
.
- 并且因为
delayedQuery.cancel == undefined
,你得到了提到的 TypeError
。
当您调用 delayedQuery()
时,您 return 去抖函数,而不是调用去抖函数的结果。由于 debounce
return 是一个带有 cancel 方法的去抖动函数,而 useCallback
接受一个函数,因此定义 delayedQuery
如下:
const delayedQuery = useCallback(debounce(updateQuery, 500), []);
问题是导入了错误的 lodash 函数。具体我原来是导入的:
import { debounce } from 'lodash/fp';
(根据我的部分理解)这是一个更适用于函数式编程技术的包装器。
在这种情况下,我需要导入:
import { debounce } from 'lodash';
我正在尝试在 React 函数组件中使用 lodash 的 debouncer 方法。当我尝试创建 debouncer-wrapped 回调时,我收到
TypeError: Expected a function
在 useCallback 语句处。我已尝试完成三个或四个示例,但其中 none 个可以在我现有的应用程序中使用。我最近的尝试是 here.
const [userQuery, setUserQuery] = useState("")
const [deb, setDeb] = useState("");
const updateQuery = () => {
setDeb(userQuery)
};
//const delayedQuery = useCallback(debounce(updateQuery, 500), []);
//const delayedQuery = useCallback(debounce(updateQuery, 500), [userQuery]);
const delayedQuery = useCallback(() => debounce(updateQuery, 500), [userQuery]);
const onChange = e => {
setUserQuery(e.target.value);
};
useEffect(() => {
delayedQuery();
// Cancel the debounce on useEffect cleanup.
return delayedQuery.cancel;
}, [userQuery, delayedQuery]);
代码在没有 debounce 包装器和 useEffect 中的相关 return 的情况下整体运行(当然没有任何 debouncing)。
评论中显示了其他变体,但都会导致相同的错误。
我对 React 还算满意,所以我对 React 的理解还有很多差距,这可能是问题所在。
编辑
该消息读给我听,好像 debounce 不被识别为函数。我没有收到有关尝试使用 import { debounce } from 'lodash/has';
或 import { debounce } from 'lodash/fp';
错误结果:
我假设提到的 TypeError
是在 useEffect
期间抛出的,因为您没有提供任何堆栈跟踪。
编辑 感谢@Ori Drori 的评论和建议:
将 delayedQuery
更改为以下内容:
const delayedQuery = useCallback(debounce(updateQuery, 500), []);
这样,您将拥有去抖动方法的记忆值,无论如何这将是一个回调,具有可用的 cancel
属性.
上一个答案(仅供参考):
那么您可以尝试将 useEffect
更改为以下内容:
useEffect(() => {
const query = delayedQuery();
query();
// Cancel the denounce on useEffect cleanup
return query.cancel;
}, [userQuery, delayedQuery]);
说明
您可以查看不同类型的方法和回调。我从头说起:
useCallback
只接受任何方法,return 是一个新方法,它将简单地调用提供的方法。它将匹配所提供方法的签名。- 反过来,提供的回调是一个简单的箭头函数,return是一个
debounce
d 方法。 - 根据 lodash 文档,
debounce
d 方法可以立即调用,cancel
ed 或flush
ed。
这导致我们在您的 useEffect
中出现以下内容:
delayedQuery
是一个回调。- 您调用
delayedQuery()
,其中钩子调用箭头函数。 - 箭头函数调用
debounce
和 return 的值 — 去抖动的updateQuery
! - BUT: 此时,您的查询尚未被调用!此外,由于 只有 return 类型的回调 是去抖函数,所以没有 属性
delayedQuery.cancel
. - 并且因为
delayedQuery.cancel == undefined
,你得到了提到的TypeError
。
当您调用 delayedQuery()
时,您 return 去抖函数,而不是调用去抖函数的结果。由于 debounce
return 是一个带有 cancel 方法的去抖动函数,而 useCallback
接受一个函数,因此定义 delayedQuery
如下:
const delayedQuery = useCallback(debounce(updateQuery, 500), []);
问题是导入了错误的 lodash 函数。具体我原来是导入的:
import { debounce } from 'lodash/fp';
(根据我的部分理解)这是一个更适用于函数式编程技术的包装器。
在这种情况下,我需要导入:
import { debounce } from 'lodash';