Как использовать Redux Provider с реакцией

Я следил за документацией ReduxJS здесь: Использование с React

В конце документа упоминается использование объекта провайдера, я завернул свой компонент приложения в провайдера следующим образом:

import React from 'react'
import ReactDOM from 'react-dom'
import { createStore } from 'redux'
import { Provider } from 'react-redux'
import RootReducer from './app/reducers'
import App from './app/app'

const store = createStore(RootReducer)

ReactDOM.render(
  <Provider store={store}>
    <App />
  </Provider>,
  document.getElementById('root')
)

Однако на этом документация заканчивается. Как мне забрать магазин, предоставленный провайдером внутри компонентов?

Ответ 1

Лучший способ получить доступ к вашему хранилищу через компонент - это использовать функцию connect(), как описано в документации. Это позволяет сопоставлять создателей состояния и действий с вашим компонентом и автоматически передавать их в качестве обновлений вашего магазина. Кроме того, по умолчанию он будет проходить в dispatch как this.props.dispatch. Вот пример из документов:

import { connect } from 'react-redux'
import { setVisibilityFilter } from '../actions'
import Link from '../components/Link'

const mapStateToProps = (state, ownProps) => {
  return {
    active: ownProps.filter === state.visibilityFilter
  }
}

const mapDispatchToProps = (dispatch, ownProps) => {
  return {
    onClick: () => {
      dispatch(setVisibilityFilter(ownProps.filter))
    }
  }
}

const FilterLink = connect(
  mapStateToProps,
  mapDispatchToProps
)(Link)

export default FilterLink

Обратите внимание, что connect фактически создает новый компонент, который обертывает ваш существующий! Этот шаблон называется Компоненты более высокого порядка и, как правило, является предпочтительным способом расширения функциональности компонента в React (над такими вещами, как наследование или mixins).

Из-за того, что он имеет довольно много оптимизаций производительности и, как правило, менее подвержен ошибкам, разработчики Redux почти всегда рекомендуют использовать connect для прямого доступа к хранилищу, однако, если у вас есть очень веская причина для более низкого уровня доступ, компонент Provider делает его таким, чтобы все его дети могли получить доступ к хранилищу через this.context:

class MyComponent {
  someMethod() {
    doSomethingWith(this.context.store);
  }
}

Ответ 2

Спасибо за ответ, но ему не хватает одного важного бита, который фактически находится в документации.

Если contextTypes не определен, то контекст будет пустым.

Поэтому мне пришлось добавить для него следующее:

  static contextTypes = {
    store: PropTypes.object.isRequired
  }