SWR:React 应用中的数据获取和缓存库

2025-02-19 08:30:11

SWR Logo

在现代 Web 应用开发中,高效的数据获取和缓存管理是至关重要的。SWR 是一个用于 React 应用的数据获取和缓存库,提供了自动刷新、去重请求和集中式缓存等功能,适用于现代 Web 应用开发。本文将详细介绍 SWR 的主要功能、特点以及使用方法,帮助读者更好地了解和使用这款优秀的工具。

主要功能

自动刷新

SWR 提供了自动刷新功能,能够定期重新获取数据,确保数据的实时性和准确性。自动刷新功能使得应用能够及时更新数据,提升用户体验。

去重请求

SWR 支持去重请求功能,能够避免在短时间内对同一数据进行多次请求。去重请求功能减少了不必要的网络流量,提高了应用的性能。

集中式缓存

SWR 提供了集中式缓存功能,能够集中管理应用中的所有数据缓存。集中式缓存功能确保了数据的一致性和高效性,减少了重复数据的获取。

本地存储

SWR 支持将数据缓存存储在本地存储中,如浏览器的 localStoragesessionStorage。本地存储功能使得应用在离线状态下也能访问数据,提升应用的可用性。

错误处理

SWR 提供了强大的错误处理功能,能够捕获和处理数据获取过程中的错误。错误处理功能确保了应用的稳定性和可靠性,提升了用户体验。

按需加载

SWR 支持按需加载数据,能够在用户需要时才进行数据获取。按需加载功能减少了初始加载时间,提高了应用的响应速度。

依赖管理

SWR 支持依赖管理功能,能够根据依赖关系自动重新获取数据。依赖管理功能确保了数据的一致性和准确性,减少了手动管理的复杂性。

预取数据

SWR 提供了预取数据功能,能够在用户访问页面之前预先获取数据。预取数据功能提升了页面加载速度,提高了用户体验。

过期策略

SWR 支持多种过期策略,能够根据不同的需求设置数据的过期时间。过期策略功能确保了数据的新鲜度和一致性,减少了过时数据的使用。

服务器端渲染

SWR 支持服务器端渲染(SSR),能够在服务器端预先获取数据并渲染页面。服务器端渲染功能提升了页面的初始加载速度和 SEO 性能,适用于需要快速加载和搜索引擎优化的应用。

使用方法

安装 SWR

  1. 安装依赖: 确保你的系统上已经安装了 Node.js 和 npm。如果没有安装,可以通过以下命令进行安装:

    • Ubuntu/Debian:

      curl -fsSL https://deb.nodesource.com/setup_16.x | sudo -E bash -
      sudo apt-get install -y nodejs
      
    • macOS:

      brew install node
      
    • Windows: 下载并安装 Node.js from Node.js 官网

  2. 安装 SWR: 使用 npm 安装 SWR:

    npm install swr
    

基本使用

  1. 导入 SWR: 导入 SWR 库:

    import useSWR from 'swr';
    
  2. 获取数据: 使用 useSWR 钩子获取数据:

    function Profile() {
      const { data, error } = useSWR('/api/user', fetcher);
    
      if (error) return <div>Failed to load</div>;
      if (!data) return <div>Loading...</div>;
    
      return <div>Hello {data.name}!</div>;
    }
    
  3. 定义 Fetcher: 定义一个 fetcher 函数来获取数据:

    const fetcher = (url) => fetch(url).then((res) => res.json());
    

自动刷新

  1. 设置自动刷新: 设置自动刷新间隔:
    function Profile() {
      const { data, error } = useSWR('/api/user', fetcher, { refreshInterval: 3000 });
    
      if (error) return <div>Failed to load</div>;
      if (!data) return <div>Loading...</div>;
    
      return <div>Hello {data.name}!</div>;
    }
    

去重请求

  1. 使用去重请求: SWR 默认支持去重请求,确保同一数据不会被多次请求:
    function Profile() {
      const { data, error } = useSWR('/api/user', fetcher);
    
      if (error) return <div>Failed to load</div>;
      if (!data) return <div>Loading...</div>;
    
      return <div>Hello {data.name}!</div>;
    }
    

集中式缓存

  1. 使用集中式缓存: SWR 默认使用集中式缓存,确保数据的一致性和高效性:
    function Profile() {
      const { data, error } = useSWR('/api/user', fetcher);
    
      if (error) return <div>Failed to load</div>;
      if (!data) return <div>Loading...</div>;
    
      return <div>Hello {data.name}!</div>;
    }
    

本地存储

  1. 使用本地存储: 配置 SWR 使用本地存储:
    import useSWR from 'swr';
    import useSWRConfig from 'swr';
    
    const fetcher = (url) => fetch(url).then((res) => res.json());
    
    function Profile() {
      const { data, error } = useSWR('/api/user', fetcher, {
        refreshInterval: 3000,
        revalidateOnFocus: true,
        revalidateOnReconnect: true,
        dedupingInterval: 2000,
        refreshWhenHidden: false,
        refreshWhenOffline: false,
        focusThrottleInterval: 5000,
        loadingTimeout: 3000,
        refreshInterval: 0,
        refreshWhenHidden: false,
        refreshWhenOffline: false,
        revalidateOnFocus: true,
        revalidateOnReconnect: true,
        refreshInterval: 0,
        refreshWhenHidden: false,
        refreshWhenOffline: false,
      });
    
      if (error) return <div>Failed to load</div>;
      if (!data) return <div>Loading...</div>;
    
      return <div>Hello {data.name}!</div>;
    }
    

错误处理

  1. 处理错误: 使用 error 对象处理数据获取过程中的错误:
    function Profile() {
      const { data, error } = useSWR('/api/user', fetcher);
    
      if (error) return <div>Failed to load</div>;
      if (!data) return <div>Loading...</div>;
    
      return <div>Hello {data.name}!</div>;
    }
    

按需加载

  1. 按需加载数据: 使用 useSWR 钩子按需加载数据:
    function Profile({ userId }) {
      const { data, error } = useSWR(userId ? `/api/user/${userId}` : null, fetcher);
    
      if (error) return <div>Failed to load</div>;
      if (!data) return <div>Loading...</div>;
    
      return <div>Hello {data.name}!</div>;
    }
    

依赖管理

  1. 管理依赖关系: 使用 useSWR 钩子管理依赖关系:
    function UserProfile({ userId }) {
      const { data: user, error: userError } = useSWR(userId ? `/api/user/${userId}` : null, fetcher);
      const { data: posts, error: postsError } = useSWR(user ? `/api/user/${user.id}/posts` : null, fetcher);
    
      if (userError || postsError) return <div>Failed to load</div>;
      if (!user || !posts) return <div>Loading...</div>;
    
      return (
        <div>
          <h1>{user.name}</h1>
          <ul>
            {posts.map((post) => (
              <li key={post.id}>{post.title}</li>
            ))}
          </ul>
        </div>
      );
    }
    

预取数据

  1. 预取数据: 使用 useSWR 钩子预取数据:
    import { useEffect } from 'react';
    import useSWR from 'swr';
    
    const fetcher = (url) => fetch(url).then((res) => res.json());
    
    function Profile({ userId }) {
      const { data, error } = useSWR(userId ? `/api/user/${userId}` : null, fetcher);
    
      if (error) return <div>Failed to load</div>;
      if (!data) return <div>Loading...</div>;
    
      return <div>Hello {data.name}!</div>;
    }
    
    function PreloadProfile({ userId }) {
      useSWR(userId ? `/api/user/${userId}` : null, fetcher);
      return null;
    }
    
    function App() {
      useEffect(() => {
        // 预取用户数据
        useSWR('/api/user/1', fetcher);
      }, []);
    
      return (
        <div>
          <PreloadProfile userId={1} />
          <Profile userId={1} />
        </div>
      );
    }
    

过期策略

  1. 设置过期策略: 配置数据的过期时间:
    function Profile() {
      const { data, error } = useSWR('/api/user', fetcher, { refreshInterval: 3000 });
    
      if (error) return <div>Failed to load</div>;
      if (!data) return <div>Loading...</div>;
    
      return <div>Hello {data.name}!</div>;
    }
    

服务器端渲染

  1. 配置服务器端渲染: 使用 SWR 进行服务器端渲染:
    import { unstable_getServerSession } from 'next-auth/next';
    import { useSWR } from 'swr';
    
    const fetcher = (url) => fetch(url).then((res) => res.json());
    
    export async function getServerSideProps(context) {
      const session = await unstable_getServerSession(context.req, context.res, authOptions);
      const user = await fetcher(`/api/user/${session.user.id}`);
    
      return {
        props: {
          fallback: {
            [`/api/user/${session.user.id}`]: user,
          },
        },
      };
    }
    
    function Profile({ fallback }) {
      const { data, error } = useSWR('/api/user/1', fetcher, { fallback });
    
      if (error) return <div>Failed to load</div>;
      if (!data) return <div>Loading...</div>;
    
      return <div>Hello {data.name}!</div>;
    }
    
    export default Profile;
    

总结

SWR 是一个用于 React 应用的数据获取和缓存库,提供了自动刷新、去重请求、集中式缓存等功能,适用于现代 Web 应用开发。无论是自动刷新、去重请求、集中式缓存、本地存储、错误处理、按需加载、依赖管理、预取数据、过期策略还是服务器端渲染,SWR 都能满足用户的各种需求。

vercel
React Hooks库用于远程数据获取。
TypeScript
MIT
31.1 k