当我试图访问react组件中的存储时,@connect工作得很好。但我该如何在其他代码中访问它呢。例如:让我们说我想使用授权令牌来创建我的axios实例,可以在我的应用程序中全局使用,实现这一点的最佳方法是什么?

这是我的api。js

// tooling modules
import axios from 'axios'

// configuration
const api = axios.create()
api.defaults.baseURL = 'http://localhost:5001/api/v1'
api.defaults.headers.common['Authorization'] = 'AUTH_TOKEN' // need the token here
api.defaults.headers.post['Content-Type'] = 'application/json'

export default api

现在我想从我的商店访问一个数据点,这是什么样子,如果我试图在一个react组件中使用@connect获取它

// connect to store
@connect((store) => {
  return {
    auth: store.auth
  }
})
export default class App extends Component {
  componentWillMount() {
    // this is how I would get it in my react component
    console.log(this.props.auth.tokens.authorization_token) 
  }
  render() {...}
}

有什么见解或工作流模式吗?


当前回答

像@sanchit一样,如果您已经全局定义了axios实例,那么提议的中间件是一个很好的解决方案。

你可以创建一个这样的中间件:

function createAxiosAuthMiddleware() {
  return ({ getState }) => next => (action) => {
    const { token } = getState().authentication;
    global.axios.defaults.headers.common.Authorization = token ? `Bearer ${token}` : null;

    return next(action);
  };
}

const axiosAuth = createAxiosAuthMiddleware();

export default axiosAuth;

像这样使用它:

import { createStore, applyMiddleware } from 'redux';
const store = createStore(reducer, applyMiddleware(axiosAuth))

它将在每个操作上设置令牌,但您只能侦听例如更改令牌的操作。

其他回答

导出我的store变量

export const store = createStore(rootReducer, applyMiddleware(ReduxThunk));

在action文件或者你的文件中需要导入这个(store)

Import {store} from "./path…";

这一步用函数从存储变量中获取状态

const state = store.getState();

获取你的app的所有状态

你可以使用从createStore函数返回的store对象(它应该已经在应用程序初始化的代码中使用了)。然后,您可以使用该对象通过store. getstate()方法或store.subscribe(listener)订阅存储更新来获取当前状态。

您甚至可以将此对象保存到window属性,以便从应用程序的任何部分访问它(如果您真的需要它的话)。商店)

更多信息可以在Redux文档中找到。

像@sanchit一样,如果您已经全局定义了axios实例,那么提议的中间件是一个很好的解决方案。

你可以创建一个这样的中间件:

function createAxiosAuthMiddleware() {
  return ({ getState }) => next => (action) => {
    const { token } = getState().authentication;
    global.axios.defaults.headers.common.Authorization = token ? `Bearer ${token}` : null;

    return next(action);
  };
}

const axiosAuth = createAxiosAuthMiddleware();

export default axiosAuth;

像这样使用它:

import { createStore, applyMiddleware } from 'redux';
const store = createStore(reducer, applyMiddleware(axiosAuth))

它将在每个操作上设置令牌,但您只能侦听例如更改令牌的操作。

找到解决办法了。所以我在我的api util中导入store并在那里订阅它。在侦听器函数中,我用新获取的令牌设置了axios的全局默认值。

这是我的新api.js的样子:

// tooling modules
import axios from 'axios'

// store
import store from '../store'
store.subscribe(listener)

function select(state) {
  return state.auth.tokens.authentication_token
}

function listener() {
  let token = select(store.getState())
  axios.defaults.headers.common['Authorization'] = token;
}

// configuration
const api = axios.create({
  baseURL: 'http://localhost:5001/api/v1',
  headers: {
    'Content-Type': 'application/json',
  }
})

export default api

也许它可以进一步改进,因为目前它似乎有点不优雅。我以后可以做的是向我的商店添加一个中间件,然后在那里设置令牌。

对于TypeScript 2.0,它看起来是这样的:

MyStore.ts

export namespace Store {

    export type Login = { isLoggedIn: boolean }

    export type All = {
        login: Login
    }
}

import { reducers } from '../Reducers'
import * as Redux from 'redux'

const reduxStore: Redux.Store<Store.All> = Redux.createStore(reducers)

export default reduxStore;

MyClient.tsx

import reduxStore from "../Store";
{reduxStore.dispatch(...)}