我正在使用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())