在 useEffect 上使用方法时遇到困难、缺少依赖项和 useCallback 错误?
Having difficulty using a method on useEffect, missing dependency and useCallback error?
这是我的代码:
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 has a missing dependency: 'dfEventQuery'. Either
include it or remove the dependency array
但是当我将它添加到数组中时:[shopWelcomeSent, history, dfEventQuery] 我得到这个错误:
The 'dfEventQuery' function makes the dependencies of useEffect Hook
(at line 201) change on every render. To fix this, wrap the
'dfEventQuery' definition into its own 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
的依赖项。
但老实说,我希望 Eslint 不会抱怨缺少依赖项,因为在您的代码中它将在相关渲染周期中重新创建,并且无论如何都不会发生 "stale closure" 问题。
[UPD] 在线程 https://github.com/facebook/react/issues/14920#issuecomment-467212561 中找到了类似的情况,但如果这是预期的(以及为什么)或者是否合法地从 useEffect 的部门中获得这样的功能,则看不到任何评论。
这是我的代码:
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 has a missing dependency: 'dfEventQuery'. Either include it or remove the dependency array
但是当我将它添加到数组中时:[shopWelcomeSent, history, dfEventQuery] 我得到这个错误:
The 'dfEventQuery' function makes the dependencies of useEffect Hook (at line 201) change on every render. To fix this, wrap the 'dfEventQuery' definition into its own 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
的依赖项。
但老实说,我希望 Eslint 不会抱怨缺少依赖项,因为在您的代码中它将在相关渲染周期中重新创建,并且无论如何都不会发生 "stale closure" 问题。
[UPD] 在线程 https://github.com/facebook/react/issues/14920#issuecomment-467212561 中找到了类似的情况,但如果这是预期的(以及为什么)或者是否合法地从 useEffect 的部门中获得这样的功能,则看不到任何评论。