【问题标题】:How Do I Use useReducer with useQuery?如何将 useReducer 与 useQuery 一起使用?
【发布时间】:2021-03-01 01:01:27
【问题描述】:
import api from "api";
import { Loader } from "components/base";
import { useReducer } from "react";
import { useQuery } from "react-query";

function reducer(state, { type, payload }) {
  switch (type) {
    case "init":
      return state.concat(payload);
    default:
      throw new Error();
  }
}

function Table() {
  const [workers, dispatch] = useReducer(reducer, []);

  const fetchWorkers = async () => {
    const workersData = await api.index();
    return workersData;
  };

  const { status, data, error } = useQuery("", fetchWorkers);

  switch (status) {
    case "loading":
      return <Loader />;

    case "error":
      return <p className="text-red-600">{error.message}</p>;

    case "success":
      dispatch({ type: "init", payload: data });
      return <p>Success!</p>;

    default:
      return <p>????</p>;
  }
}

export default Table;

上面的代码导致无限重新渲染?为什么? ????

一旦useQuerystatus === "success" 通信,为什么我不能只dispatch 并初始化我的数据?我应该怎么做呢? ????

我删除了useQuery,只是处理了useEffect,没有任何问题-数据回来了,我dispatched。

useQuery 有什么不同?

【问题讨论】:

    标签: reactjs use-reducer react-query


    【解决方案1】:

    您的代码导致无限重新渲染,因为您在加载数据后每次渲染都调用dispatch

    case "success":
      // since the switch() statement runs every render, as long as it's "success"
      // we'll call dispatch, update the reducer, and then force a re-render
      // thus causing a loop
      dispatch({ type: "init", payload: data });
      return <p>Success!</p>;
    

    有两种方法可以避免这种情况。

    1. 不要将数据放入 reducer。看起来你没有任何理由在你的示例代码中这样做,如果在更多地方需要数据,你也可以在那里调用useQuery(我对这个库不是很熟悉但我想他们有一些缓存策略)。

    2. 如果您确实需要 reducer 中的数据,请在效果内进行调度,以便它仅在状态更改为 success 时运行

      React.useEffect(() => {
        if (status === 'success') {
          dispatch({ type: 'init', payload: data });
        },
      }, [status]); // since `status` is in the dependency, this effect only runs when its value changes
      

    一般的教训是尽量避免直接在组件的渲染体中调用改变状态的函数——更喜欢效果和回调。

    【讨论】:

    • 是的。我认为 ? react-query 应该在我们与服务器实时执行大量 async 的事情时使用。在这里我只是在玩弄数据的本地状态更新可能不合适 - 没有真正的 CRUD 后端。
    猜你喜欢
    • 2022-01-14
    • 2020-10-03
    • 2019-10-23
    • 2020-10-30
    • 2022-01-10
    • 1970-01-01
    • 2021-12-20
    • 2020-05-02
    • 1970-01-01
    相关资源
    最近更新 更多