Почему очистка хука useEffect видит результат RTKQ как isLoading и как избежать этой проблемы?

У меня есть компонент функции React (компонент маршрута), который должен что-то делать, когда он отключен (т.е. пользователь нажимает кнопку "Назад" в браузере) и содержит следующие соответствующие строки:

      // ...

const params = useParams<ISomeInterfaceHere>();

// ...

// I verified that `data` below actually loads but it does not last until the component unmounts.
const { data, isLoading, isError } = useGetSomethingQuery(params.x, {
  refetchOnMountOrArgChange: true,
});

// ...

useEffect(() => {
  return () => {
    // current state:
    //
    // isLoading === true
    // isError === false
    // data === undefined
  };
}, []);

// ...

Это связано с useParams крючок который от react-routerупаковка? Это ошибка в RTKQ или, если нет, каково определенное поведение? И, самое главное, как я могу получить последнее определенное значение data непосредственно перед размонтированием компонента?

Сообщения об ошибках отсутствуют.

Обновление 1

Я использую:

      "react": "^16.14.0",
"react-router": "^5.1.2",
"react-router-dom": "^5.1.2",
"@reduxjs/toolkit": "^1.6.0",

Обновление 2

Я уверен что params не обновляются, даже params.x. Я также перешел на @reduxjs/toolkit v1.6.1 и у меня такая же проблема.

Обновление 3

Песочница кода с изолированной проблемой находится здесь. Мне кажется, это ошибка в RTKQ.

Обновление 4

Я открыл здесь отчет об ошибке GH .

1 ответ

Вы создаете этот обратный вызов очистки при первом рендеринге. С этого момента этот обратный вызов будет удерживать устаревшие переменные от первого рендеринга до тех пор, пока он не будет выполнен, даже если между ними происходят сотни рендеров.

Это не имеет ничего общего с RTKQ - это просто принцип работы React. Если вы хотите получить доступ к актуальным значениям в этой очистке, вам придется туннелировать его через ссылку:

      const { data, isLoading, isError } = useGetSomethingQuery(params.x, {
  refetchOnMountOrArgChange: true,
});

const ref = useRef({data, isLoading, isError})
useEffect(() => { ref.current = {data, isLoading, isError} }, [data, isLoading, isError])

// ...

useEffect(() => {
  return () => {
    console.log(ref.current)
  };
}, []);
Другие вопросы по тегам