React Router删除操作中如何实现action到loader的数据传递?
解决React Router Dom中Action到Loader的数据传递问题
先修正你当前Action代码的问题
你的action函数存在两个关键问题:
axios.delete是异步操作,但未使用await,导致函数直接返回空值,无法捕获接口响应或表单数据。- 最终没有返回有效数据,后续组件或loader无法获取处理结果。
修正后的action代码:
action: async ({ request, params }) => { const data = Object.fromEntries(await request.formData()); try { if (request.credentials === "same-origin") { const response = await axios.delete(`${url}/toys/${params.toyId}`); // 返回接口响应和表单数据 return { response, data }; } } catch (error) { // 捕获错误并返回 return { error: error.message }; } return null; }
方案一:直接用useActionData获取Action返回值(推荐)
不需要通过loader中转,DeletedView组件可直接通过React Router提供的useActionData hook获取action的返回结果,这是最直接的方式:
import { useActionData } from "react-router-dom"; function DeletedView() { const actionData = useActionData(); if (actionData?.error) { return <div>删除失败:{actionData.error}</div>; } if (actionData?.data) { const { toyName, toyDescription } = actionData.data; return ( <div> <h3>删除成功!</h3> <p>已删除玩具:{toyName}</p> <p>描述:{toyDescription}</p> </div> ); } return <div>处理中...</div>; }
方案二:通过重定向携带搜索参数,Loader读取参数
如果一定要通过loader传递数据,可在action删除成功后,重定向到当前路由并携带表单数据作为URL搜索参数,再在loader中解析这些参数:
1. 修改Action函数:
import { redirect } from "react-router-dom"; action: async ({ request, params }) => { const data = Object.fromEntries(await request.formData()); try { if (request.credentials === "same-origin") { await axios.delete(`${url}/toys/${params.toyId}`); // 重定向到当前路由,携带编码后的搜索参数 return redirect(`/toys/${params.toyId}/destroy?toyName=${encodeURIComponent(data.toyName)}&toyDescription=${encodeURIComponent(data.toyDescription)}`); } } catch (error) { return redirect(`/toys/${params.toyId}/destroy?error=${encodeURIComponent(error.message)}`); } }
2. 修改Loader函数:
loader: async ({ request, params }) => { const urlParams = new URL(request.url).searchParams; return { params, toyName: urlParams.get("toyName"), toyDescription: urlParams.get("toyDescription"), error: urlParams.get("error") }; }
3. 在DeletedView中用useLoaderData获取数据:
import { useLoaderData } from "react-router-dom"; function DeletedView() { const loaderData = useLoaderData(); if (loaderData.error) { return <div>删除失败:{loaderData.error}</div>; } if (loaderData.toyName) { return ( <div> <h3>删除成功!</h3> <p>已删除玩具:{loaderData.toyName}</p> <p>描述:{loaderData.toyDescription}</p> </div> ); } return <div>处理中...</div>; }
内容的提问来源于stack exchange,提问作者revvy
相关产品推荐
相关产品推荐

