首页 > 解决方案 > React.useEffect 中的访问令牌通常有效,但在刷新/重新加载页面时返回未定义

问题描述

我在 Gatsby 中有一个简单的 React 页面/组件,可以进行 API 调用。对于这个 API 调用,我需要一个令牌。我使用gatsby-theme-auth0通过他们的AuthService对象获取这个令牌。

我正在我的useEffect. 它看起来像这样:

 useEffect(() => {
    //defining the async function
    async function fetchFromAPI() {
      try {
        const data = await fetchData()
        setData(data)
      }
    }
    
    //executing the async function:
    fetchFromAPI()
  }, [])

fetchData()目前异步调用的函数useEffect如下所示:

async function fetchData() {
  
  const client = new GraphQLClient(SERVER_URL_GRAPHQL)
  let aToken = await AuthService.getAccessToken()
  client.setHeader('authorization', `Bearer ${aToken}`)
  const query = ...

  const data = await client.request(query)
  return data
}

所有这些通常都有效。当我从我的 SPA 中的不同页面导航到此页面时,它可以工作。但是,当我重新加载页面时,它不会。访问令牌 ( aToken) 然后返回为undefined.

但是: 当我把整个电话都包裹起来时,我可以让事情顺利进行。setTimeout然后访问令牌恢复正常并且不是undefined. 所以我想首先需要初始化一些东西AuthService才能被调用?我只是不确定如何确保这一点。

但这不是我想在生产中做的。现在我想知道为什么会这样。也许我使用useEffect了错误的方式?不幸的是,到目前为止,我还没有在网上或 github 上找到任何东西。我敢肯定这个问题是相当基本的。

编辑:该AuthService.getAccessToken()方法可以在这里找到它的一部分gatsby-theme-auth0

编辑:为了澄清,服务器确实收到了请求并发回{"error":"jwt malformed"}- 这是有道理的,因为它是undefined.

标签: javascriptreactjsasync-awaituse-effect

解决方案


我不知道您是否已经在挂钩中进行了身份验证,但是您需要在进行任何 api 调用之前检查用户是否已通过身份验证,尤其是那些在 app init 上的调用。处理身份验证时是否有钩子/上下文?如果有,您可以稍微更改一下代码

 const {isAuthenticated} = useContext(userAuthenticatedContext)

 useEffect(() => {
    //defining the async function
    async function fetchFromAPI() {
      try {
        const data = await fetchData()
        setData(data)
      }
    }
    
    //executing the async function:
    if(isAuthenticated) fetchFromAPI()
  }, [isAuthenticated])

这种方式isAuthenticated是您的依赖项,useEffect当值更改时它将再次运行,isAuthenticated并且在您进行检查时它不会失败,然后再进行调用。


推荐阅读