Возникли проблемы с использованием метода useEffect, отсутствием зависимости и ошибкой useCallback? - PullRequest
0 голосов
/ 06 января 2020

Это мой код:

  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' 'function меняет зависимости useEffect Hook (в строке 201) на каждом рендере. Чтобы исправить это, оберните определение 'dfEventQuery' в его собственный метод useCallback () Hook

Я застрял с ним несколько часов и просто не могу обернуть голову, почему это не работает?

1 Ответ

2 голосов
/ 06 января 2020

, поэтому в этом случае проще просто обернуть функцию в 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.

Но честно говоря, я ожидаю, что Эслинт не будет жаловаться на отсутствующую зависимость, поскольку в вашем коде она будет воссоздана в соответствующем цикле рендеринга, и проблема «устаревшего закрытия» в любом случае не возникнет.

[UPD] найти аналогичный случай в потоке https://github.com/facebook/react/issues/14920#issuecomment -467212561 , но не вижу комментариев ни в том случае, если это ожидается (и почему), либо если * git имеет такой функция вне использования useEffect.

...