从 React Native 中的 api 拦截器(组件外部)重定向到屏幕

Redirect to screen from an api interceptor (outside of component) in React Native

我正在开发一个使用 JWT 令牌对请求进行身份验证的 React Native 应用程序。为此,我创建了 axios 请求和响应拦截器,以将令牌添加到每个请求(请求拦截器),并在响应具有 401 HTTP 状态(响应拦截器)时将用户重定向到登录屏幕。

问题是我还没有找到在组件外部进行重定向的方法。下面的代码位于 API 服务中,每当我想要进行 API 调用时都会导入该服务。

我需要做什么才能重定向到我的登录屏幕,因为此服务是无状态的并且不关心它是从哪个组件调用的?

// Response interceptor
axiosInstance.interceptors.response.use(
  response => {
    // Do something with response data
    if (response.status === 401) {
      deviceStorage.removeData('token');
      // TODO:
      // Redirect to login page
    }
    return response;
  },
  error => {
    // Do something with response error
    return Promise.reject(error);
  }
);

对于此功能,我认为您需要使用 Redux

这是一篇描述 redux 和 redux saga 的简单中型文章。 https://medium.com/@tkssharma/understanding-redux-react-in-easiest-way-part-1-81f3209fc0e5

使用 redux-saga 作为中间件并使用 es6 中的生成器函数新特性

不,您不需要为此使用 Redux。如果你使用的是 React Navigation,你可以这样做。你可以从任何地方访问

https://reactnavigation.org/docs/en/navigating-without-navigation-prop.html

你可以这样使用:

import Component_1 from 'PATH TO IT'
import Component_2 from 'PATH TO IT'

this.state = {   
        status: 1
    }


render(){
    if(this.state.status == 1){
          return( <Component_1 onChange={(value)=> this.setState({status: value}) }/> )//Point => A
    }else if(this.state.status == 2){ 
             return( <Component_2 /> )
    }

这里我们使用两个组件作为一个 parent 的 child,在点 A 我们将一个函数传递给 child(称为 props ) 使我们能够根据我们的工作更改 child 内部 parent 的状态,并且当状态更改时 component_1 将被卸载并且 component_2 将被装载(例如登录页面)。 在 component_1 中,我们可以在道具中使用该功能来更改页面,如下所示:

if (response.status === 401) {
  deviceStorage.removeData('token');
  // TODO:
  this.props.onChange(2) // here you can redirect to that component
}

按照官方文档:Navigating without the navigation prop

尝试这样的事情

// App.js

import { createStackNavigator, createAppContainer } from 'react-navigation';
import NavigationService from './NavigationService';

const TopLevelNavigator = createStackNavigator({ /* ... */ })

const AppContainer = createAppContainer(TopLevelNavigator);

export default class App extends React.Component {
  // ...

  render() {
    return (
      <AppContainer
        ref={navigatorRef => {
          NavigationService.setTopLevelNavigator(navigatorRef);
        }}
      />
    );
  }
}

// NavigationService.js

import { NavigationActions } from 'react-navigation';

let _navigator;

function setTopLevelNavigator(navigatorRef) {
  _navigator = navigatorRef;
}

function navigate(routeName, params) {
  _navigator.dispatch(
    NavigationActions.navigate({
      routeName,
      params,
    })
  );
}

// add other navigation functions that you need and export them

export default {
  navigate,
  setTopLevelNavigator,
};