跳转到内容
主菜单
主菜单
移至侧栏
隐藏
导航
首页
最近更改
随机页面
MediaWiki帮助
代码酷
搜索
搜索
中文(中国大陆)
外观
创建账号
登录
个人工具
创建账号
登录
未登录编辑者的页面
了解详情
贡献
讨论
编辑“︁
Next.js SWR钩子
”︁(章节)
页面
讨论
大陆简体
阅读
编辑
编辑源代码
查看历史
工具
工具
移至侧栏
隐藏
操作
阅读
编辑
编辑源代码
查看历史
常规
链入页面
相关更改
特殊页面
页面信息
外观
移至侧栏
隐藏
您的更改会在有权核准的用户核准后向读者展示。
警告:
您没有登录。如果您进行任何编辑,您的IP地址会公开展示。如果您
登录
或
创建账号
,您的编辑会以您的用户名署名,此外还有其他益处。
反垃圾检查。
不要
加入这个!
= Next.js SWR钩子 = == 介绍 == '''SWR'''(Stale-While-Revalidate)是Next.js中一个强大的数据获取钩子,由Vercel团队开发。它基于HTTP缓存策略"Stale-While-Revalidate",允许应用程序在后台重新验证数据的同时立即显示缓存(可能过时)的数据。SWR特别适合需要实时数据更新的应用程序,同时保持优秀的用户体验。 SWR的主要特点包括: * 轻量级且易于使用 * 内置缓存和请求去重 * 自动重新验证数据 * 支持TypeScript * 可定制的重新验证策略 == 基本用法 == 要使用SWR,首先需要安装它: <syntaxhighlight lang="bash"> npm install swr # 或 yarn add swr </syntaxhighlight> 然后可以在组件中这样使用: <syntaxhighlight lang="javascript"> import useSWR from 'swr' function Profile() { const { data, error, isLoading } = useSWR('/api/user', fetcher) if (error) return <div>加载失败</div> if (isLoading) return <div>加载中...</div> return <div>你好, {data.name}!</div> } </syntaxhighlight> 这里: * '''/api/user''' - 数据请求的key(通常是API端点) * '''fetcher''' - 一个函数,接收key并返回数据 * '''data''' - 获取的数据 * '''error''' - 错误对象 * '''isLoading''' - 加载状态 == 创建fetcher函数 == fetcher是一个简单的异步函数,通常使用fetch或axios: <syntaxhighlight lang="javascript"> const fetcher = (...args) => fetch(...args).then(res => res.json()) </syntaxhighlight> 或者使用axios: <syntaxhighlight lang="javascript"> import axios from 'axios' const fetcher = url => axios.get(url).then(res => res.data) </syntaxhighlight> == 高级特性 == === 自动重新验证 === SWR会自动在以下情况下重新验证数据: * 当窗口重新获得焦点时 * 当网络重新连接时 * 可以配置定时重新验证 === 条件获取 === 可以基于条件禁用数据获取: <syntaxhighlight lang="javascript"> const { data } = useSWR(shouldFetch ? '/api/data' : null, fetcher) </syntaxhighlight> === 依赖请求 === 可以创建依赖其他SWR请求的请求: <syntaxhighlight lang="javascript"> function MyProjects() { const { data: user } = useSWR('/api/user') const { data: projects } = useSWR(() => '/api/projects?uid=' + user.id) if (!projects) return '加载中...' return '你有' + projects.length + '个项目' } </syntaxhighlight> === 全局配置 === 可以使用SWRConfig提供全局配置: <syntaxhighlight lang="javascript"> import { SWRConfig } from 'swr' function App() { return ( <SWRConfig value={{ refreshInterval: 3000, fetcher: (resource, init) => fetch(resource, init).then(res => res.json()) }} > <Profile /> </SWRConfig> ) } </syntaxhighlight> == 实际应用案例 == === 实时仪表盘 === 假设我们正在构建一个实时监控仪表盘: <syntaxhighlight lang="javascript"> function Dashboard() { const { data: stats, error } = useSWR('/api/stats', fetcher, { refreshInterval: 5000 // 每5秒刷新一次 }) if (error) return <ErrorAlert /> if (!stats) return <LoadingSpinner /> return ( <div> <h1>系统状态</h1> <div>当前用户: {stats.users}</div> <div>活跃会话: {stats.sessions}</div> <div>服务器负载: {stats.load}%</div> </div> ) } </syntaxhighlight> === 分页数据 === SWR可以很好地处理分页: <syntaxhighlight lang="javascript"> function Posts({ pageIndex }) { const { data: posts } = useSWR(`/api/posts?page=${pageIndex}`, fetcher) return ( <ul> {posts?.map(post => ( <li key={post.id}>{post.title}</li> ))} </ul> ) } </syntaxhighlight> == 性能优化 == === 预加载数据 === 可以在页面导航前预加载数据: <syntaxhighlight lang="javascript"> import { mutate } from 'swr' function Link({ href }) { return ( <a href={href} onMouseEnter={() => mutate(href, fetch(href).then(res => res.json()))} > 链接 </a> ) } </syntaxhighlight> === 乐观更新 === SWR支持乐观UI更新: <syntaxhighlight lang="javascript"> function LikeButton({ id }) { const { data, mutate } = useSWR(`/api/post/${id}`, fetcher) const handleLike = async () => { const newLikes = (data.likes || 0) + 1 // 乐观更新UI mutate({ ...data, likes: newLikes }, false) // 发送请求到API await fetch(`/api/post/${id}/like`, { method: 'POST' }) // 重新验证确保数据正确 mutate() } return <button onClick={handleLike}>点赞 ({data?.likes || 0})</button> } </syntaxhighlight> == 错误处理 == SWR提供了多种错误处理方式: <syntaxhighlight lang="javascript"> function Profile() { const { data, error } = useSWR('/api/user', fetcher, { onErrorRetry: (error, key, config, revalidate, { retryCount }) => { // 404错误时不重试 if (error.status === 404) return // 最多重试10次 if (retryCount >= 10) return // 5秒后重试 setTimeout(() => revalidate({ retryCount: retryCount + 1 }), 5000) } }) if (error) { if (error.status === 404) { return <div>用户不存在</div> } return <div>加载失败</div> } if (!data) return <div>加载中...</div> return <div>你好, {data.name}!</div> } </syntaxhighlight> == 与Next.js集成的最佳实践 == === 预取数据 === 在Next.js中,可以结合getStaticProps或getServerSideProps预取数据: <syntaxhighlight lang="javascript"> export async function getStaticProps() { const user = await fetcher('/api/user') return { props: { fallback: { '/api/user': user } } } } function Profile({ fallback }) { return ( <SWRConfig value={{ fallback }}> <UserProfile /> </SWRConfig> ) } </syntaxhighlight> === 无限加载 === 结合useSWRInfinite实现无限加载: <syntaxhighlight lang="javascript"> import useSWRInfinite from 'swr/infinite' const getKey = (pageIndex, previousPageData) => { if (previousPageData && !previousPageData.length) return null // 到达末尾 return `/api/items?page=${pageIndex}&limit=10` // SWR key } function Items() { const { data, size, setSize } = useSWRInfinite(getKey, fetcher) if (!data) return <div>加载中...</div> const items = data.flat() return ( <> <ul> {items.map(item => ( <li key={item.id}>{item.name}</li> ))} </ul> <button onClick={() => setSize(size + 1)}>加载更多</button> </> ) } </syntaxhighlight> == 常见问题 == === 为什么选择SWR而不是直接使用fetch或axios? === SWR提供了: * 自动缓存 * 自动重新验证 * 请求去重 * 更简单的错误处理 * 更优雅的加载状态管理 === SWR适合所有数据获取场景吗? === 虽然SWR非常强大,但在以下情况下可能需要考虑其他方案: * 需要完全控制请求生命周期 * 需要处理非常复杂的请求链 * 需要与特定的状态管理库深度集成 == 总结 == SWR是Next.js应用中数据获取的强大工具,它简化了客户端数据管理,提供了优秀的用户体验和开发者体验。通过智能缓存、自动重新验证和丰富的配置选项,SWR可以帮助开发者构建高效、响应迅速的现代Web应用程序。 [[Category:后端框架]] [[Category:Next.js]] [[Category:Next.js数据获取]]
摘要:
请注意,所有对代码酷的贡献均被视为依照知识共享署名-非商业性使用-相同方式共享发表(详情请见
代码酷:著作权
)。如果您不希望您的文字作品被随意编辑和分发传播,请不要在此提交。
您同时也向我们承诺,您提交的内容为您自己所创作,或是复制自公共领域或类似自由来源。
未经许可,请勿提交受著作权保护的作品!
取消
编辑帮助
(在新窗口中打开)