2016-07-19 6 views
74

@connect funktioniert gut, wenn ich versuche, auf den Speicher innerhalb einer Reaktionskomponente zuzugreifen. Aber wie sollte ich auf etwas anderes Code zugreifen? Zum Beispiel: Angenommen, ich möchte ein Autorisierungstoken für die Erstellung meiner Axios-Instanz verwenden, die global in meiner App verwendet werden kann. Was wäre der beste Weg, dies zu erreichen?Was ist der beste Weg, auf den Redox-Speicher außerhalb einer Reaktionskomponente zuzugreifen?

Das ist mein 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 

Jetzt möchte ich von meinem Speicher einen Datenpunkt zuzugreifen, ist hier, was das aussehen würde, wenn ich versuchte, es in einem reagieren Komponente zu holen @connect

mit
// 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() {...} 
} 

Irgendwelche Einblicke oder Workflow-Muster da draußen?

+0

Sie Ich will nicht, dass du Axios bist nstance in einer redux Middleware zu leben? Es wird von all Ihrer Anwendung auf diese Weise zur Verfügung gestellt werden –

+0

Sie können die 'API' in' App' Klasse importieren und nach Erhalt des Autorisierungs-Tokens können Sie 'api.defaults.headers.common ['Authorization'] = this.props. auth.tokens.authorization_token; ', und gleichzeitig können Sie es auch in localStorage speichern. Wenn der Benutzer die Seite aktualisiert, können Sie überprüfen, ob das Token in localStorage vorhanden ist. Wenn dies der Fall ist, können Sie es festlegen. Ich denke, es wird am besten sein, das Token auf einem API-Modul zu setzen, sobald Sie es bekommen haben. –

+0

Dan Abromov bietet ein Beispiel in der Warteschlange Warteschlange hier: https://github.com/reactjs/redux/issues/916 – chrisjlee

Antwort

6

Sie können das Objekt store verwenden, das von der Funktion createStore zurückgegeben wird (die bereits in Ihrem Code in der App-Initialisierung verwendet werden sollte). Dann können Sie dieses Objekt verwenden, um den aktuellen Status mit der Methode store.getState() oder store.subscribe(listener) abzurufen, um Aktualisierungen zu speichern.

können Sie auch sicher dieses Objekt window Eigenschaft zuzugreifen es von jedem Teil der Anwendung, wenn Sie es wirklich wollen (window.store = store)

Mehr Infos here

+6

klingt irgendwie hacky zu speichern "speichern" auf die "Fenster" – Vic

+2

@Vic Sicher ist es :) Und normalerweise willst du es nicht machen. Ich wollte nur erwähnen, dass Sie mit dieser Variable machen können, was Sie wollen. Wahrscheinlich wäre es die beste Idee, sie in einer Datei zu speichern, in der Sie Ihre "createStore" Leben erstellt haben, und dann einfach von dort importieren. – trashgenerator

15

eine Lösung gefunden. Also importiere ich das Geschäft in meine API und abonniere es dort. Und in dieser Listener-Funktion setze ich die globalen Standardwerte der Axios mit meinem neu geholten Token. Diese

ist, was mein neues api.js wie folgt aussieht:

// 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 

Vielleicht kann sie weiter verbessert werden, führen zur Zeit es ein wenig unelegant scheint. Was ich später tun könnte, ist, eine Middleware zu meinem Geschäft hinzuzufügen und das Token dann und dort zu setzen.

+0

können Sie teilen, wie Ihre 'store.js' Datei aussieht? – Vic

+0

genau das, was ich suchte, danke eine Tonne @subodh –

69

Exportieren Sie den Speicher von dem Modul, das Sie mit createStore aufgerufen haben. Dann können Sie sicher sein, dass beides erstellt wird und den globalen Fensterbereich nicht verschmutzen wird.

MyStore.js

store = createStore(myReducer); export store;

oder

store = createStore(myReducer); export default store;

MyClient.js

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

oder wenn Sie verwendet Standard

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

+3

WARNUNG für isomorphe Apps: tun diese Server-Seite wird die Redux-Shop über alle Ihre Benutzer teilen !!! –

+0

Die Frage fragt nicht, wie mehrere Speicher für mehrere Benutzer verwaltet werden oder wie der serverseitige Status verwaltet wird. Es stellt einfach Fragen, wie auf den Speicher zuzugreifen, der in dem angegebenen Code definiert wurde. –

+0

Die Frage besagt auch nicht explizit "Browser". Da Redux und JavaScript sowohl auf dem Server als auch auf dem Browser verwendet werden können, ist es viel sicherer, spezifisch zu sein. –

-1

Für Typoskript 2.0 es würde wie folgt aussehen:

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(...)} 
+0

Wenn Sie abstimmen, fügen Sie bitte einen Kommentar warum. – Ogglas

+0

Wird abgelehnt, weil Ihre Antwort keine Erklärung enthält und TypeScript anstelle von Javascript verwendet. – Will

+0

@Will Danke, dass du sagst warum. Imao der Code erfordert keine Spezifikation, aber wenn Sie möchten, dass etwas spezifisch erklärt, sagen Sie bitte was. TypeScript wird zwar verwendet, aber wenn die Typings entfernt werden, wird der gleiche Code in ES6 problemlos ausgeführt. – Ogglas