使用SWR时如何正确传递headers?

How to properly pass headers when using SWR?

我决定尝试将大部分 API 功能转移到 SWR,因为它让我可以做更多事情!

问题

但是,我遇到了一个大问题,我不知道如何正确地将 headers 传递给 SWR。我查看了文档等等,但似乎没有任何效果。我正在使用 Twitch API、Next.js 和 NextAuth 来处理令牌、会话等。我在下面留下了我的 GitHub 存储库以及我目前正在尝试使用的代码。

注:

我控制台记录错误 return 如果错误发生,当我访问页面 /dash 它说 failed to load 但是没有错误的控制台日志?

Github Repo

import axios from "axios";
import Link from "next/link";
import {
  VStack,
  Heading,
  Divider,
  Text,
  Box,
  Badge,
  Center,
} from "@chakra-ui/react";
import { useSession } from "next-auth/react"
import useSWR from 'swr'

const fetcher = (url) => {
  const { data: session, status } = useSession()
  axios
    .get(url, { 
        headers: { 
          'Authorization': `Bearer ${session.accessToken}`,
          'Client-Id': `${process.env.TWITCH_CLIENT_ID}`
        }})
    .then((res) => res.data);
}
     
function Dash () {
  const { data, error } = useSWR(`https://api.twitch.tv/helix/streams/key?broadcaster_id=630124067`,fetcher)
  
  if (error) return (
    console.log(error),
    <div>Failed to load</div>
  )
  if (!data) return <div>loading...</div>

  return (
    <VStack>
      <Text>{data.user_name}</Text>
    </VStack>
  )
}

export default Dash

TL;DR: 您可以使用数组作为 useSWR 中的 key 参数,将 multiple arguments 传递给 fetcher函数。


首先,useSession 是一个 React 挂钩,只能在 React component/another 挂钩的顶层调用。这样可以避免破坏 Rules of Hooks.

其次,您应该将 useSession 调用移至 Dash 组件。然后,当 session 存在时,您可以有条件地调用 fetcher(参见 Conditional Fetching),并使用数组作为 keyaccessToken 传递给 fetcher 方法参数.

function Dash() {
    const { data: session } = useSession()

    const { data, error } = useSWR(
        session ? ['https://api.twitch.tv/helix/streams/key?broadcaster_id=630124067', session.accessToken] : null, 
        fetcher
    )
  
    // Remaining code
}

最后,您的 fetcher 函数必须稍微修改以接受 accessToken 参数。请注意,您还需要 axios 调用中的 return 语句才能正确 return 数据。

const fetcher = (url, accessToken) => {
    return axios
        .get(url, { 
            headers: { 
                'Authorization': `Bearer ${accessToken}`,
                'Client-Id': `${process.env.TWITCH_CLIENT_ID}`
            }
        })
        .then((res) => res.data);
}