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)
如果loadingLineisfalse和loadingBaris 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)