我尝试为我的请求实现axios拦截器。 因此,当错误响应被禁止时(401),我想清除令牌并导航到登录屏幕。 但是,当我想从axios文件中的react navigation v5调用useNavigation时,它总是显示这样的错误。
React Hook "useNavigation" is called in function "refreshAccessToken" that is neither a React function component nor a custom React Hook function. React component names must start with an uppercase letter.
这是我的axios文件代码,
import axios from 'axios'
import AsyncStorage from '@react-native-community/async-storage'
import {useNavigation} from '@react-navigation/native'
import {generateRandomString, getDeviceInfo} from '../helper/helper'
const base = axios.create({
baseURL: '------',
timeout: 500000,
headers: {
'Content-Type': 'application/json'
}
})
async function refreshAccessToken() {
const navigation = useNavigation()
try {
const refreshToken = await AsyncStorage.getItem('refreshToken')
const response = await base.get('------', {
refreshToken
})
await AsyncStorage.setItem('accessToken', response.data.accessToken)
console.log('Response from refresh access token ', response)
return Promise.resolve(response.data)
} catch (error) {
console.log('Error from refresh access token', error.response)
if (error.response.data.errors.flag === 'INVALID_REFRESH_TOKEN') {
await AsyncStorage.removeItem('refreshToken')
await AsyncStorage.removeItem('accessToken')
}
return Promise.reject(error)
}
}
base.interceptors.request.use(
async function (config) {
const accessToken = await AsyncStorage.getItem('accessToken')
config.headers.authorization = accessToken
const deviceInfo = await getDeviceInfo()
const latitude = await AsyncStorage.getItem('latitude')
const longitude = await AsyncStorage.getItem('longitude')
config.headers['accept-language'] = 'id-ID'
config.headers['version'] = '1.0.0'
config.headers['date'] = new Date().toUTCString()
config.headers['x-coordinate'] = `${latitude};${longitude}`
config.headers['x-trace-id'] = generateRandomString()
config.headers['x-device'] = `${deviceInfo.deviceType}/${deviceInfo.deviceName}/${deviceInfo.deviceVersion}/${deviceInfo.deviceUid}`
return config
},
function (error) {
return Promise.reject(error)
}
)
base.interceptors.response.use(
(response) => response,
async (error) => {
const originalRequest = error.config
if (error.response.status === 403 && !originalRequest._retry) {
originalRequest._retry = true
const accessToken = await refreshAccessToken()
originalRequest.headers.Authorization = accessToken
return axios(originalRequest)
}
return Promise.reject(error)
}
)
export default base
答案 0 :(得分:0)
您不能,挂钩只能在内部组件中调用。不过,有一种指南介绍了如何navigate without the navigation prop用于这种情况。
您还可以发送事件(通过自定义事件发射器),并在应用中可以使用导航道具的其他任何地方设置侦听器。