如何在动态URL场景下使用useSWRMutation?含请求配置疑问
关于useSWRMutation的两个疑问
我有一个点击按钮发送请求的组件,代码如下:
function Component() { function handleClick () { // Send request } return ( <button onClick={handleClick}>Click me</button> ) }
我想使用useSWRMutation发送POST请求(比如POST /api/clicks/:clickId),写了如下示例代码:
async function sendClick (url, { arg }) { await fetch(url, { // 疑问1:是否应该写成`${url}/${arg.clickId}`? method: 'POST', headers: { "Content-Type": "application/json" }, body: JSON.stringify(arg) }); } function Component() { const { trigger } = useSWRMutation('/api/clicks/', sendClick); // 疑问2:此处应填什么URL(key)?1)/api/clicks/:clickId 2)/api/clicks 3)空值? function handleClick () { trigger({ id: "clickId", otherData: [] }); } return ( <button onClick={handleClick}>Click me</button> ) }
我有两个疑问:
- 发送动态URL(如
/api/clicks/:clickId)的请求时,useSWRMutation应使用什么key? - 我不需要缓存或缓存失效,只是需要
isLoading(或isMutating)状态才用这个hook,这样合适吗?
问题1:动态URL对应的useSWRMutation key配置
首先明确:useSWRMutation的第一个参数(key)主要用于标识当前mutation操作,同时会作为第一个参数传入你的请求函数(比如示例里的sendClick)。
针对你的动态URL场景,推荐这么做:
- 把基础路径
/api/clicks作为key传入useSWRMutation - 在请求函数
sendClick里,用基础路径拼接arg里的clickId生成完整请求URL
修改后的代码示例:
async function sendClick(baseUrl, { arg }) { // 从参数中拆分出clickId和其他请求数据 const { clickId, ...restData } = arg; await fetch(`${baseUrl}/${clickId}`, { method: 'POST', headers: { "Content-Type": "application/json" }, body: JSON.stringify(restData) }); } function Component() { // 用基础路径作为key const { trigger } = useSWRMutation('/api/clicks', sendClick); function handleClick () { // 触发时传入clickId和其他数据 trigger({ clickId: "your-click-id", otherData: [] }); } return ( <button onClick={handleClick}>Click me</button> ) }
关于你提到的疑问1:是的,必须拼接成${url}/${arg.clickId},因为你的后端接口路径是/api/clicks/:clickId,原始的/api/clicks只是基础路径,不拼接的话请求会发错地址。
另外补充几个key的可选方案:
- 你也可以直接把完整动态URL作为key(比如
/api/clicks/your-click-id),但每次clickId变化key都会改变,适合单次固定id的mutation场景,但不如基础路径拼接的方式灵活。 - 不要填空值,key是mutation的唯一标识,空值可能导致和其他同key的mutation逻辑冲突。
问题2:仅用useSWRMutation获取加载状态是否合适
完全合适,理由如下:
useSWRMutation本身就是为mutation操作设计的,默认不会缓存mutation结果,所以即使你不需要缓存功能,也不会有额外的缓存负担。- 它提供的
isMutating状态、错误捕获(error)、触发逻辑(trigger)都是现成的,比自己手动用useState管理加载状态更简洁。
对比手动管理加载状态的写法:
// 手动管理加载状态的示例 function Component() { const [isLoading, setIsLoading] = useState(false); const [error, setError] = useState(null); async function handleClick() { setIsLoading(true); try { await fetch(`/api/clicks/your-click-id`, { method: 'POST', headers: { "Content-Type": "application/json" }, body: JSON.stringify({ otherData: [] }) }); } catch (err) { setError(err); } finally { setIsLoading(false); } } return <button onClick={handleClick} disabled={isLoading}>Click me</button>; }
可以看到,用useSWRMutation能省去手动切换加载状态、捕获错误的重复代码,代码更简洁易维护。所以哪怕你只需要加载状态,用它也是非常合适的选择。
内容的提问来源于stack exchange,提问作者Roman Mahotskyi
相关产品推荐
相关产品推荐

