Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/reactjs/26.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Reactjs 使用上下文和Axios拦截器注销所有页面_Reactjs_React Hooks_React Context - Fatal编程技术网

Reactjs 使用上下文和Axios拦截器注销所有页面

Reactjs 使用上下文和Axios拦截器注销所有页面,reactjs,react-hooks,react-context,Reactjs,React Hooks,React Context,我在React组件之外,但需要更新我的身份验证上下文“AuthContext”,以删除现有用户,从而将用户从所有登录页面中完全注销 我可以使用redux发送redux操作。如何使用上下文实现同样的效果 下面是我的代码。。。logOutAll函数不工作,因为不能在React组件或函数之外使用useContext 感谢那些成功实施此计划的人提供的建议。谢谢 import { useContext } from "react" import axios from "axi

我在React组件之外,但需要更新我的身份验证上下文“AuthContext”,以删除现有用户,从而将用户从所有登录页面中完全注销

我可以使用redux发送redux操作。如何使用上下文实现同样的效果

下面是我的代码。。。logOutAll函数不工作,因为不能在React组件或函数之外使用useContext

感谢那些成功实施此计划的人提供的建议。谢谢

import { useContext } from "react"
import axios from "axios"

import { AuthContext } from "../context/authContext"

const api = axios.create({
  baseURL: "http://localhost:5000/api",
  headers: {
    "Content-Type": "application/json",
  },
})

/**
 intercept any error responses from the api
 and check if the token is no longer valid.
 ie. Token has expired or user is no longer
 authenticated.
 logout the user if the token has expired
**/

// const logOutAll = () => {
//   const { authStatus, setAuthStatus } = useContext(AuthContext)
//   console.log(authStatus)
//   setAuthStatus({
//     ...authStatus,
//     isAuthenticated: false,
//     isLoading: false,
//     user: null,
//   })
// }

api.interceptors.response.use(
  res => res,
  err => {
    if (err.response.status === 401) {
      console.log("log out all")
      logOutAll() //! CANNOT WORK BECAUSE UseContext cannot be called outside React function 
      or component

    }
    return Promise.reject(err)
  }
)

export default api

我在app.js文件中设置了我的axios拦截器,它似乎工作正常

const App = () => {
  const { authStatus, setAuthStatus } = useContext(AuthContext)

  useEffect(() => {
    const checkLoggedIn = async () => {
      let token = localStorage.getItem("@token")
      if (token === null) {
        localStorage.setItem("@token", "")
        token = ""
      }
      const res = await api.get("/users/me", {
        headers: {
          authorization: token,
        },
      })

      //TODO
      // const token = localStorage.getItem("@token")
      // console.log("TOKEN", token)
      // if (token) {
      //   setAuthToken(token)
      // }
      // const res = await api.get("http://localhost:5000/api/users/me")

      console.log(res)

      setAuthStatus(authStatus => ({
        ...authStatus,
        isAuthenticated: true,
        isLoading: false,
        user: res.data,
      }))
    }
    checkLoggedIn()
  }, [setAuthStatus])

  api.interceptors.response.use(
    res => res,
    err => {
      if (err.response.status === 401) {
        setAuthStatus({
          ...authStatus,
          isAuthenticated: false,
          isLoading: false,
          user: null,
        })
      }
      return Promise.reject(err)
    }
  )

我在app.js文件中设置了我的axios拦截器,它似乎工作正常

const App = () => {
  const { authStatus, setAuthStatus } = useContext(AuthContext)

  useEffect(() => {
    const checkLoggedIn = async () => {
      let token = localStorage.getItem("@token")
      if (token === null) {
        localStorage.setItem("@token", "")
        token = ""
      }
      const res = await api.get("/users/me", {
        headers: {
          authorization: token,
        },
      })

      //TODO
      // const token = localStorage.getItem("@token")
      // console.log("TOKEN", token)
      // if (token) {
      //   setAuthToken(token)
      // }
      // const res = await api.get("http://localhost:5000/api/users/me")

      console.log(res)

      setAuthStatus(authStatus => ({
        ...authStatus,
        isAuthenticated: true,
        isLoading: false,
        user: res.data,
      }))
    }
    checkLoggedIn()
  }, [setAuthStatus])

  api.interceptors.response.use(
    res => res,
    err => {
      if (err.response.status === 401) {
        setAuthStatus({
          ...authStatus,
          isAuthenticated: false,
          isLoading: false,
          user: null,
        })
      }
      return Promise.reject(err)
    }
  )

你被卡在哪里了?你是在挣扎于提供商的概念,还是其他什么?如果您使用的是钩子,那么您可以在钩子本身内部定义所有API请求,或者在使用上下文的情况下定义上下文提供程序。为此,我设想您将创建一个AuthProvider,它包装您的应用程序并定义所有相关的API相关处理程序,并将用户向下传递到应用程序的其余部分,以及您希望应用程序能够访问的任何处理程序。如果你需要这个结构,我可以提供一个基本的例子。@James,谢谢。我的axios拦截器放在一个既不是React组件的api.js文件中,因此我无法从那里访问或更新我的auth上下文。我已经转移到我的app.js文件,它是一个React组件,到目前为止,它似乎工作正常。我在下面的答案中输入了代码。如果您有改进代码的建议,请接受任何建议。谢谢:)你被卡在哪里了?你是在挣扎于提供商的概念,还是其他什么?如果您使用的是钩子,那么您可以在钩子本身内部定义所有API请求,或者在使用上下文的情况下定义上下文提供程序。为此,我设想您将创建一个AuthProvider,它包装您的应用程序并定义所有相关的API相关处理程序,并将用户向下传递到应用程序的其余部分,以及您希望应用程序能够访问的任何处理程序。如果你需要这个结构,我可以提供一个基本的例子。@James,谢谢。我的axios拦截器放在一个既不是React组件的api.js文件中,因此我无法从那里访问或更新我的auth上下文。我已经转移到我的app.js文件,它是一个React组件,到目前为止,它似乎工作正常。我在下面的答案中输入了代码。如果您有改进代码的建议,请接受任何建议。谢谢:)请确保这符合您的期望。此时,useEffect将在每次
setAuthStatus
更改时运行,它将在
App
的每次渲染中执行此操作,除非您已将setAuthStatus包装在AuthContext中的
useCallback
,目前为止它似乎工作正常。我想检查应用程序的每个渲染上的身份验证状态,以确保用户已通过身份验证。如果用户未通过身份验证,我需要更新上下文以将用户设置为Unauthenticated如果有更好的地方放置axios拦截器,我将欢迎任何反馈。谢谢:)在每次渲染时发出API请求几乎肯定不是您想要的。这将对您的服务器造成沉重负担,不会增加任何价值。您可能只需要在发出API请求(即获取新数据或发布内容)时检查用户是否已登录。如果你真的想进行定期检查,看看它们是否仍然经过身份验证,那么最好使用
setInterval
,每x秒/分钟轮询一次服务器,这样至少你可以控制这个频率。渲染只是关于你的UI如何更新,应该与身份验证无关。我的方法是基于那些在线课程。如。这段代码来自一个在线课程,他们在每个应用程序渲染器上都进行了检查,以确保这符合您的预期。此时,useEffect将在每次
setAuthStatus
更改时运行,它将在
App
的每次渲染中执行此操作,除非您已将setAuthStatus包装在AuthContext中的
useCallback
,目前为止它似乎工作正常。我想检查应用程序的每个渲染上的身份验证状态,以确保用户已通过身份验证。如果用户未通过身份验证,我需要更新上下文以将用户设置为Unauthenticated如果有更好的地方放置axios拦截器,我将欢迎任何反馈。谢谢:)在每次渲染时发出API请求几乎肯定不是您想要的。这将对您的服务器造成沉重负担,不会增加任何价值。您可能只需要在发出API请求(即获取新数据或发布内容)时检查用户是否已登录。如果你真的想进行定期检查,看看它们是否仍然经过身份验证,那么最好使用
setInterval
,每x秒/分钟轮询一次服务器,这样至少你可以控制这个频率。渲染只是关于你的UI如何更新,应该与身份验证无关。我的方法是基于那些在线课程。如。这段代码来自在线课程,他们在每次应用程序渲染时都会检查