Каков наилучший способ получить доступ к хранилищу резервов вне реагирующего компонента?

87

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

Любые идеи или шаблоны рабочих процессов там?

  • 0
    Вы не хотите, чтобы ваш экземпляр Axios жил в избыточном промежуточном программном обеспечении? Это будет доступно всем вашим приложениям таким образом
  • 0
    Вы можете импортировать api в класс App и после получения токена авторизации вы можете сделать api.defaults.headers.common['Authorization'] = this.props.auth.tokens.authorization_token; , И в то же время вы можете хранить его и в localStorage, поэтому, когда пользователь обновляет страницу, вы можете проверить, существует ли токен в localStorage, и если он есть, вы можете установить его. Я думаю, что будет лучше установите токен на модуль API, как только вы его получите.
Показать ещё 2 комментария
Теги:
react-redux
redux

5 ответов

79

Экспортируйте хранилище из модуля, с которым вы вызвали 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(...)

  • 42
    ПРЕДУПРЕЖДЕНИЕ для изоморфных приложений: выполнение этой серверной части разделит хранилище редуксов среди всех ваших пользователей !!!
  • 0
    Вопрос не в том, как управлять несколькими магазинами для нескольких пользователей или как управлять состоянием на стороне сервера; Это простые вопросы, как получить доступ к магазину, который был определен в указанном коде.
Показать ещё 8 комментариев
19

Найден решение. Поэтому я импортирую хранилище в свой 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

Возможно, он может быть еще лучше, потому что в настоящее время он кажется немного неэлегантным. То, что я могу сделать позже, - добавить промежуточное ПО в мой магазин и установить токен тогда и там.

  • 1
    store.js ли вы поделиться, как store.js ваш файл store.js ?
  • 0
    именно то, что я искал, спасибо огромное @subodh
Показать ещё 2 комментария
8

Вы можете использовать объект store, который возвращается из функции createStore (которая должна быть уже использована в вашем коде при инициализации приложения). Чем вы можете использовать этот объект, чтобы получить текущее состояние с помощью метода store.getState() или store.subscribe(listener), чтобы подписаться на сохранение обновлений.

Вы можете даже защитить этот объект от свойства window, чтобы получить доступ к нему из любой части приложения, если вы действительно этого хотите (window.store = store)

Подробнее здесь

  • 15
    звучит как-то бестолково, чтобы сохранить store в window
  • 3
    @Vic Конечно, это так :) И обычно ты не хочешь этого делать. Я просто хотел упомянуть, что с этой переменной вы можете делать все, что захотите. Вероятно, лучшая идея будет сохранить его в файле, в котором вы создали свой «createStore» жизни, а затем просто импортировать из него.
4

Кажется, что Middleware - это путь.
Обратитесь официальная документация и эта проблема в их репо

0

Для 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(...)}
  • 2
    Если вы отказываетесь, добавьте комментарий, почему.
  • 1
    Отказался, потому что в вашем ответе нет объяснения и используется TypeScript, а не Javascript.
Показать ещё 1 комментарий

Ещё вопросы

Сообщество Overcoder
Наверх
Меню