Next.js 中为何 API 请求会重复?

在使用 Next.js 开发应用过程中,我们可能会遇到 API 请求重复的问题。这种情况通常会导致应用性能下降,用户体验变差,甚至可能会影响服务器的稳定性。那么,为什么会出现 API 请求重复的情况呢?本文将深入探讨这个问题,并提供解决方案。

问题背景

在 Next.js 中,我们通常会使用 getStaticPropsgetServerSideProps 方法来获取数据,并将数据传递给页面组件进行渲染。这些方法通常会在服务器端执行,然后将数据传递给客户端进行渲染。但是,如果我们在客户端进行了数据请求,那么可能会出现 API 请求重复的情况。

例如,我们有一个页面组件 Post,它需要获取一篇文章的详细信息。我们可以在 getServerSideProps 方法中获取文章数据,并将其传递给页面组件进行渲染。但是,如果我们在页面组件中使用了 useEffect 方法来获取文章数据,那么就会出现 API 请求重复的情况。

import { useState, useEffect } from 'react'

function Post({ post }) {
  const [postDetail, setPostDetail] = useState(null)

  useEffect(() => {
    fetch(`/api/posts/${post.id}`)
      .then(res => res.json())
      .then(data => setPostDetail(data))
  }, [post.id])

  return (
    <div>
      <h1>{post.title}</h1>
      <p>{post.content}</p>
      <p>{postDetail && postDetail.content}</p>
    </div>
  )
}

export async function getServerSideProps({ params }) {
  const { id } = params
  const res = await fetch(`https://api.example.com/posts/${id}`)
  const post = await res.json()
  return { props: { post } }
}

export default Post

在上面的代码中,我们在 useEffect 方法中使用了 post.id 作为依赖项,这意味着每当 post.id 发生变化时,useEffect 方法就会重新执行。而当我们在客户端进行页面跳转时,post.id 会发生变化,因此 useEffect 方法就会重新执行,从而导致 API 请求重复。

解决方案

为了解决 API 请求重复的问题,我们可以使用 useSWR 这个库。useSWR 是一个 React Hooks 库,它可以帮助我们管理数据请求并对数据进行缓存,从而避免重复请求。

首先,我们需要在页面组件中引入 useSWR

import useSWR from 'swr'

然后,我们可以使用 useSWR 来获取文章数据:

function Post({ post }) {
  const { data: postDetail } = useSWR(`/api/posts/${post.id}`, url => fetch(url).then(res => res.json()))

  return (
    <div>
      <h1>{post.title}</h1>
      <p>{post.content}</p>
      <p>{postDetail && postDetail.content}</p>
    </div>
  )
}

在上面的代码中,我们使用了 useSWR 来获取文章数据。useSWR 的第一个参数是 API 地址,第二个参数是一个函数,用于获取数据。useSWR 会对数据进行缓存,并在需要时重新获取数据。这样,即使我们在客户端进行页面跳转,也不会出现 API 请求重复的情况。

总结

在 Next.js 中,API 请求重复的问题可能会导致应用性能下降、用户体验变差、服务器稳定性受到影响等问题。为了解决这个问题,我们可以使用 useSWR 这个库来管理数据请求并对数据进行缓存。通过使用 useSWR,我们可以避免 API 请求重复的情况,提高应用的性能和用户体验。

参考文献:

来源:JavaScript中文网 ,转载请注明来源 本文地址:https://www.javascriptcn.com/post/65c576cdadd4f0e0ff001bc5