首页 > 解决方案 > 在 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 中

我已经坚持了几个小时,只是无法理解为什么这不起作用?

标签: javascriptreactjsreact-hooksuse-effect

解决方案


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 的部门。


推荐阅读