如何在循环中使用React Query的mutate提交(变更)数据?
React Query批量提交请求并收集结果到useState
并行请求方案(推荐)
如果希望所有请求并行发送,完成后一次性更新状态,可以将批量请求逻辑封装到React Query的useMutation中,利用Promise.all处理异步请求:
import { useMutation } from '@tanstack/react-query'; import axios from 'axios'; import { useState } from 'react'; function BatchSubmitComponent() { const [values, setValues] = useState([]); const endpoints = ["group1", "group2", "group3"]; // 定义批量请求的mutation const batchPostMutation = useMutation({ mutationFn: async () => { // 生成所有请求的Promise数组 const requestPromises = endpoints.map(endpoint => axios.post(`some_link/${endpoint}`) ); // 并行执行所有请求 return Promise.all(requestPromises); }, onSuccess: (results) => { // 请求全部完成后,将结果追加到状态中 setValues(prevState => [...prevState, ...results]); }, onError: (error) => { console.error('批量请求失败:', error); } }); const handleBatchSubmit = () => { // 触发批量请求 batchPostMutation.mutate(); }; return ( <div> <button onClick={handleBatchSubmit} disabled={batchPostMutation.isLoading} > {batchPostMutation.isLoading ? '提交中...' : '批量提交'} </button> {/* 渲染结果 */} <div className="results"> {values.map((res, idx) => ( <div key={idx}>{JSON.stringify(res.data)}</div> ))} </div> </div> ); }
串行逐个请求方案
如果需要逐个发送请求(前一个完成再发下一个),可以用循环结合mutateAsync实现,每个请求成功后立即更新状态:
import { useMutation } from '@tanstack/react-query'; import axios from 'axios'; import { useState } from 'react'; function SerialSubmitComponent() { const [values, setValues] = useState([]); const endpoints = ["group1", "group2", "group3"]; // 定义单个请求的mutation const singlePostMutation = useMutation({ mutationFn: async (endpoint) => { return axios.post(`some_link/${endpoint}`); }, onSuccess: (response) => { // 单个请求成功后追加结果到状态 setValues(prevState => [...prevState, response]); }, onError: (error, endpoint) => { console.error(`请求${endpoint}失败:`, error); } }); const handleSerialSubmit = async () => { // 逐个触发请求,等待每个请求完成 for (const endpoint of endpoints) { await singlePostMutation.mutateAsync(endpoint); } }; return ( <div> <button onClick={handleSerialSubmit} disabled={singlePostMutation.isLoading} > {singlePostMutation.isLoading ? '提交中...' : '逐个提交'} </button> <div className="results"> {values.map((res, idx) => ( <div key={idx}>{JSON.stringify(res.data)}</div> ))} </div> </div> ); }
常见问题排查
之前使用Promise.all未成功,可能是以下原因:
- 未将批量请求逻辑正确封装到React Query的
mutationFn中,导致无法利用其异步状态管理 - 直接在循环中多次调用
setValues,因React状态更新的异步特性,导致状态更新被覆盖 - 未处理请求错误,单个请求失败导致整个
Promise.all抛出异常,未捕获错误导致流程中断
内容的提问来源于stack exchange,提问作者Natig Agharzayev
相关产品推荐
相关产品推荐

