javascript - 在 useEffect 上使用方法有困难,缺少依赖项和 useCallback 错误?
问题描述
这是我的代码:
const dfEventQuery = async (event: string) => {
const {
data: { result }
} = await axios.post("/api/df_event_query", { event, userId });
for (let msg of result.fulfillmentMessages) {
const botSay: MessageDataType = { speaks: "bot", msg };
setMessages(oldMessages => [...oldMessages, botSay]);
}
};
const resolveInXSeconds = (x: number) =>
new Promise(res => {
setTimeout(() => {
res(x);
}, x * 1000);
});
useEffect(() => {
dfEventQuery("Welcome");
if (inputRef.current) inputRef.current.focus();
const sendShopWelcome = async () => {
await resolveInXSeconds(1);
dfEventQuery("WELCOME_SHOP");
setShopWelcomeSent(true);
setShowChatbot(true);
};
if (window.location.pathname === "/shop" && !shopWelcomeSent) {
sendShopWelcome();
}
history.listen(() => {
if (history.location.pathname === "/shop" && !shopWelcomeSent) {
sendShopWelcome();
}
});
}, [shopWelcomeSent, history]);
我有这个错误:
React Hook useEffect 缺少依赖项:'dfEventQuery'。包括它或删除依赖数组
但是当我将它添加到数组中时: [shopWelcomeSent, history, dfEventQuery] 我得到这个错误:
'dfEventQuery' 函数使 useEffect Hook(第 201 行)的依赖关系在每次渲染时发生变化。要解决此问题,请将“dfEventQuery”定义包装到它自己的 useCallback() Hook 中
我已经坚持了几个小时,只是无法理解为什么这不起作用?
解决方案
useCallback
所以在这种情况下,将函数包装到那里列出所有依赖项会更容易:
const dfEventQuery = useCallback(async (event: string) => {
const {
data: { result }
} = await axios.post("/api/df_event_query", { event, userId });
for (let msg of result.fulfillmentMessages) {
const botSay: MessageDataType = { speaks: "bot", msg };
setMessages(oldMessages => [...oldMessages, botSay]);
}
}, [userId]);
并将其列在useEffect
's 依赖项中。
但老实说,我希望 Eslint 不会抱怨缺少依赖项,因为在您的代码中它将在相关的渲染周期中重新创建,并且无论如何都不会发生“陈旧关闭”问题。
[UPD] 在线程https://github.com/facebook/react/issues/14920#issuecomment-467212561中找到类似的案例,但如果这是预期的(以及为什么)或者是否合法拥有这样的功能超出了 useEffect 的部门。
推荐阅读
- javascript - 使用 ng-repeat 时不断出错
- api - API接受对象列表作为参数.NetCore
- javascript - 如果存储 getter 更改而不重新加载页面,则重新运行 nuxt 路由中间件?
- firebase - 不能在导航器中使用脚手架全局键的上下文
- python - 打开勒索软件保护的 Python 权限问题
- amazon-sns - AWS 10DLC 跨账户
- powershell - PowerShell 查询结果列表或字符串
- typescript - 打字稿实例类型
不像我想象的那样表现 - spring - Spring Batch / Azure 存储帐户 blob 资源 [container"foo", blob='bar'] 无法解析为绝对文件路径
- sql - 从不同列中的表函数中透视字符串