@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
Теперь я хочу получить доступ к точке данных из своего хранилища, вот что бы выглядело, если бы я пытался получить ее внутри реагирующего компонента, используя @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() {...}
}
Любые идеи или шаблоны рабочих процессов там?
Экспортируйте хранилище из модуля, с которым вы вызвали createStore. Тогда вы уверены, что оба они будут созданы и не будут загрязнять глобальное пространство окна.
MyStore.js
store = createStore(myReducer);
export store;
или
store = createStore(myReducer);
export default store;
MyClient.js
import {store} from './MyStore'
store.dispatch(...)
или если вы использовали по умолчанию
import store from './MyStore'
store.dispatch(...)
Найден решение. Поэтому я импортирую хранилище в свой api util и подписываюсь на него там. И в этой функции слушателя я устанавливаю глобальные значения по умолчанию 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
Возможно, он может быть еще лучше, потому что в настоящее время он кажется немного неэлегантным. То, что я могу сделать позже, - добавить промежуточное ПО в мой магазин и установить токен тогда и там.
store.js
ли вы поделиться, как store.js
ваш файл store.js
?
Вы можете использовать объект store
, который возвращается из функции createStore
(которая должна быть уже использована в вашем коде при инициализации приложения). Чем вы можете использовать этот объект, чтобы получить текущее состояние с помощью метода store.getState()
или store.subscribe(listener)
, чтобы подписаться на сохранение обновлений.
Вы можете даже защитить этот объект от свойства window
, чтобы получить доступ к нему из любой части приложения, если вы действительно этого хотите (window.store = store
)
Подробнее здесь
store
в window
Кажется, что Middleware
- это путь.
Обратитесь официальная документация и эта проблема в их репо
Для 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(...)}
api
в классApp
и после получения токена авторизации вы можете сделатьapi.defaults.headers.common['Authorization'] = this.props.auth.tokens.authorization_token;
, И в то же время вы можете хранить его и в localStorage, поэтому, когда пользователь обновляет страницу, вы можете проверить, существует ли токен в localStorage, и если он есть, вы можете установить его. Я думаю, что будет лучше установите токен на модуль API, как только вы его получите.