使用SWR不适用于异步提取器函数



我正在使用SWR获取数据以填充表。我正在使用以下代码:

const { data: items, error } = useSWR(fetchAllItems.name, fetchAllItems)

提取器功能看起来像这个

async function fetchAllItems() {
const response = await fetch('http://localhost:3000/items')
const data = await response.json()
return data
}

该表还具有添加新项目的选项。创建新项后,我调用mutate,让SWR获取新数据。当在开发模式下运行时,一切都很好,但是当使用next-start而不是next-dev时,它不会获取数据。在"网络"选项卡中,它显示0个请求,因此看起来从未调用fetcher函数。

从中提取数据的服务器运行正常。我已经用邮递员测试过了,它会退回所有的物品。它也可以从下一个应用程序访问,因为创建一个新项目效果很好。

编辑:经过更多的调试,我将其缩小到SWR在使用下一次启动而不是下一次开发时从不验证的事实

编辑2:这里可以找到一个具有最小可复制示例的代码沙盒https://codesandbox.io/s/elated-cherry-3ugqyi?file=/package.json。De codesandbox使用npm run dev(它调用next dev(运行程序,所以一切都很好。但是,当使用npm run build && npm run start运行它时,useSWR不再调用fetcher函数。

第三版:我已经解决了这个问题,但不明白怎么解决的。我将回迁器功能更改为:

function fetchAllItems() {
return fetch('http://localhost:3000/items').then((res) => res.json())
}

fetcher函数现在不再是异步的,但它仍然返回Promise(因为fetcher返回Promise(。如果有人能解释为什么这段代码的行为与前一段不同,那就太好了。

您的fetcher函数是正常的。之所以出现此问题,是因为在生产构建中,fetchAllItems.name解析为空字符串'',这意味着useSWR不会调用fetcher功能,因为key参数是一个错误值。

你有两种选择来解决这个问题。

#1使用硬编码字符串作为useSWR

只需在useSWR中使用一个字符串作为key参数。我推荐这种方法,因为在生产中使用fetchAllItems.name可能并不总是返回预期值。

const { data: items, error } = useSWR('fetchAllItems', fetchAllItems)

#2对fetchAllItems使用命名函数

fetchAllItems函数使用命名函数格式,而不是使用箭头函数。当您在没有async/await的情况下定义新函数时,这可能就是解决问题的原因。

export async function fetchAllItems() {
const response = await fetch('http://localhost:3000/items')
const data = await response.json()
return data
}

需要传递一个arow函数作为执行fetchAllItems函数的fetcher:

const { data: items, error } = useSWR(fetchAllItems.name, () => fetchAllItems())

最新更新