Quelle est la meilleure façon d’accéder au magasin de redux en dehors d’un composant de réaction?

@connect fonctionne très bien lorsque j’essaie d’accéder au magasin dans un composant de réaction. Mais comment dois-je y accéder dans un autre morceau de code. Par exemple: disons que je veux utiliser un jeton d’autorisation pour créer mon instance axios pouvant être utilisée globalement dans mon application, quel serait le meilleur moyen d’y parvenir?

Ceci est mon 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 

Maintenant, je veux accéder à un sharepoint données depuis mon magasin, voici à quoi cela ressemblerait si j’essayais de le récupérer dans un composant de réaction en utilisant @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() {...} } 

Des idées ou des schémas de stream de travail?

Exportez le magasin depuis le module avec lequel vous avez appelé createStore. Vous êtes alors assuré que les deux seront créés et ne pollueront pas l’espace global de la fenêtre.

MyStore.js

store = createStore(myReducer); export store;

ou

store = createStore(myReducer); export default store;

MyClient.js

import {store} from './MyStore' store.dispatch(...)

ou si vous avez utilisé par défaut

import store from './MyStore' store.dispatch(...)

Trouvé une solution. J’importe donc le magasin dans mon api util et m’y abonne. Et dans cette fonction d’écoute, je définis les valeurs par défaut globales des axios avec mon nouveau jeton récupéré.

Voici à quoi ressemble mon nouvel 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 

Peut-être que cela peut encore être amélioré, car actuellement, cela semble un peu inélégant. Ce que je pourrais faire plus tard, c’est append un middleware à mon magasin et définir le jeton à cet endroit.

Vous pouvez utiliser store object store renvoyé par la fonction createStore (qui doit déjà être utilisé dans votre code lors de l’initialisation de l’application). Vous pouvez ensuite utiliser cet object pour obtenir l’état actuel avec la méthode store.getState() ou store.subscribe(listener) pour vous abonner aux mises à jour du magasin.

Vous pouvez même enregistrer cet object dans la propriété window pour y accéder depuis n’importe quelle partie de l’application si vous le voulez vraiment ( window.store = store )

Plus d’informations peuvent être trouvées dans la documentation Redux .

Semble que Middleware est la voie à suivre.
Reportez – vous à la documentation officielle et à ce numéro sur leur repository

Comme @sanchit, le middleware proposé est une bonne solution si vous définissez déjà votre instance axios globalement.

Vous pouvez créer un middleware comme:

 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; 

Et l’utiliser comme ça:

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

Il définira le jeton à chaque action, mais vous ne pourrez écouter que les actions qui changent le jeton, par exemple.

Pour TypeScript 2.0, cela ressemblerait à ceci:

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 = Redux.createStore(reducers) export default reduxStore; 

MyClient.tsx

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

Cette question est assez ancienne, mais je pense que cela vaut la peine de partager mon idée.

Plutôt que de stocker des jetons dans un magasin Redux, je les stocke en mémoire.
* Lorsque l’application est chargée, lisez TOKEN depuis AsyncStorage (ou ailleurs) et configurez-le pour le définir sur

 import {updateToke} from 'path_to_the_below_module'; updateToken({your token}). 

Voici un extrait de code que j’ai fait.

 import Axios from "axios"; import { AsyncStorage } from 'react-native'; const AUTH_TOKEN='AUTH_TOKEN'; const BASE_URL = 'http://localhost:5001/api/v1'; let authenticationToken = {}; export const updateToken = (token) => { AsyncStorage.setItem(AUTH_TOKEN, JSON.ssortingngify(token)); authenticationToken = token; }; const networkRequest = Axios.create({ baseURL: BASE_URL, }); networkRequest.interceptors.request.use(config => { const bearer = `Bearer ${authenticationToken.access_token}`; if (bearer) { config.headers['Authorization'] = bearer; } console.log(config); return config; }, error => Promise.reject(error)); export default networkRequest; 

Simplement le moyen de l’utiliser

 import networkRequest from '...pathtothemodule'; networkRequest.get('/user/info').then(....).catch(...); 

Notez que chaque fois que vous actualisez un jeton, veillez à appeler updateToken ({votre jeton}) afin de le conserver au plus tard.

C’est une autre alternative que j’ai utilisée dans mon projet et je souhaite aller chercher vos idées.