如何在react-query中正确实现useQueries?

mmz*_*mmz 9 javascript api reactjs react-native react-query

我用来react-query在同一个 React 组件中进行两个单独的查询。我最初尝试使用两个useQuery钩子:

export default function Component() {
  const [barData, setBarData] = useState();
  const [lineData, setLineData] = useState();
  const { error: errorBar, isLoading: loadingBar } = useData(
    "barQuery",
    "BAR_TEST_SINGLE",
    setBarData
  );
  const { error: errorLine, isLoading: loadingLine } = useData(
    "lineQuery",
    "LINE_TEST",
    setLineData
  );

  const isLoading = loadingLine && loadingBar;
  const error = errorLine && errorBar;


  if (isLoading) return <LoadingSpinner title={title} />;
  if (error)
    return <InvalidStateAPI description={error.message} title={title} />;
  return (
    <>
        <Line data={lineData} />
        <Bar data={barData} />
    </>
  );
}
Run Code Online (Sandbox Code Playgroud)

useData这是从另一个文件导入的的内容:

export function useData(queryId, chartId, setData) {
  return useQuery(
    queryId,
    () =>
      fetchData(chartId, "models").then((resp) => {
        setData(resp.Item.data);
      })
  );
}
Run Code Online (Sandbox Code Playgroud)

fetchData是查询 AWS DDB 表的函数。我很高兴发布该函数,但为了简洁起见,我目前将其排除在外。

渲染Component结果出现此错误:TypeError: Cannot read properties of undefined (reading 'filter')。我怀疑抛出此错误是因为组件没有及时获取其数据进行渲染。我认为这可以通过添加 来解决const isLoading = loadingLine && loadingBar;,如本文中所建议的,但事实并非如此。

最后,根据这个SO 答案的推荐,我决定使用useQueries. 文档非常稀疏,但建议使用以下格式

const results = useQueries([
   { queryKey: ['post', 1], queryFn: fetchPost },
   { queryKey: ['post', 2], queryFn: fetchPost },
 ])
Run Code Online (Sandbox Code Playgroud)

我将原来的代码修改为以下内容:

 const results = useQueries([
   {
     queryKey: ["post", 1],
     queryFn: useData2("barQuery", "BAR_TEST_SINGLE", setBarData),
   },
   {
     queryKey: ["post", 2],
     queryFn: useData2("lineQuery", "LINE_TEST", setLineData),
   },
 ]);
Run Code Online (Sandbox Code Playgroud)

但现在我收到此错误:TypeError: _this2.options.queryFn is not a function

我的查询格式是否不正确?我该如何修复它?react-query或者,是否有其他方法可以在同一组件中运行不同的查询?

TkD*_*odo 18

不,这不是 的正确语法useQueries。您不能在 as 中传递 useQuery 挂钩queryFn-queryFn需要获取数据的函数,在您的情况下,这将是fetchData(chartId, "models").

然而,最初问题的根本原因似乎是您的条件仅等到其中一个查询完成加载:

const isLoading = loadingLine && loadingBar;
Run Code Online (Sandbox Code Playgroud)

如果loadingLineisfalseloadingBaris true,此条件将产生false,因此您将不再显示加载旋转器。如果您想等到所有查询完成加载,那就是:

const isLoading = loadingLine || loadingBar;
Run Code Online (Sandbox Code Playgroud)

最后,我想指出,将数据从react-query复制到本地状态是没有必要的。queryFnreact-query 将返回从as字段返回的结果data。我的实现看起来像这样:

export function useData(queryId, chartId) {
  return useQuery(
    [queryId, chartId],
    () => fetchData(chartId, "models")
  );
}

const { error: errorBar, isLoading: loadingBar, data: barData } = useData(
    "barQuery",
    "BAR_TEST_SINGLE",
  );
  const { error: errorLine, isLoading: loadingLine, data: lineData } = useData(
    "lineQuery",
    "LINE_TEST",
  );

  const isLoading = loadingLine || loadingBar;
Run Code Online (Sandbox Code Playgroud)

或者,也可以使用useQueries

 const results = useQueries([
   {
     queryKey: ["barQuery", "BAR_TEST_SINGLE"],
     queryFn: () => fetchData("BAR_TEST_SINGLE", "models")
   },
   {
     queryKey: ["lineQuery", "LINE_TEST"],
     queryFn: () => fetchData("LINE_TEST", "models")
   },
 ]);

const isLoading = results.some(result => result.isLoading)
Run Code Online (Sandbox Code Playgroud)

  • 当我使用“useQueries”时,我总是得到“loading”的“status”,因此我的“data”是未定义的。我该如何解决这个问题? (3认同)