Подтвердить что ты не робот

Redux, мне нужно импортировать хранилище во все мои контейнеры, если я хочу получить доступ к данным?

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

Итак, кроме импорта импортировать хранилище из "пути/в/хранить/хранить"

в каждом файле, который я хочу getState() или "dispatch", как мне получить доступ к этому состоянию, потому что, если я его не включаю, хранилище undefined.

4b9b3361

Ответ 1

В общем случае вы хотите, чтобы только компоненты контейнера верхнего уровня имели доступ к хранилищу - они передадут любые необходимые данные или диспетчеризацию действий в качестве реквизитов для своих дочерних компонентов. В этом разница между "умным" и "тупым" компонентами - "умные" компоненты знают о хранилище/состоянии Redux, в то время как "немые" компоненты просто передают им реквизит и не имеют представления о большем состоянии приложения.

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

import createStore from '../store';

const store = createStore()

class App extends Component {

  render() {
    return (
      <Provider store={store}>
        <MainAppContainer />
      </Provider>
    )
  }
}

Как вы можете видеть здесь, у меня есть отдельный файл конфигурации только для моего магазина, так как вы можете сделать много изменений и для любого удаленно сложного приложения, вы обнаружите, что делаете то же самое для таких вещей, как использование compose для применения промежуточного программного обеспечения.

Тогда любой из ваших оставшихся "умных" компонентов (обычно обертки) необходимо прослушать в магазине. Это достигается с помощью метода подключения. Это позволяет вам отображать части состояния в свойствах вашего компонента, а также отправлять действия как свойства.

import { bindActionCreators } from 'redux';
import { connect } from 'react-redux';
import * as actionCreators from './actionCreators';

const mapStateToProps = function(state){
  return {
    something: state.something,
  }
}

const mapDispatchToProps = function (dispatch) {
  return bindActionCreators({
    getSomething: actionCreators.getSomething,
  }, dispatch)
}

class MainAppContainer extends Component {

    componentDidMount() {
      //now has access to data like this.props.something, which is from store
      //now has access to dispatch actions like this.props.getSomething
    }

    render() {
        //will pass down store data and dispatch actions to child components
        return (
               <div>
                   <ChildComponent1 something={this.props.something} />
                   <ChildComponent2 getSomething={this.props.getSomething} />
               </div>
        )
    }
}

export default connect(mapStateToProps, mapDispatchToProps)(MainAppContainer)

Поскольку вы всегда передаете действия и данные диспетчеризации своему дочернему компоненту как свойства, вы просто ссылаетесь на эти компоненты с помощью this.props.

ChildComponent1 приведенный выше пример, вы увидите, что, поскольку я передал this.props.something в ChildComponent1, у него есть доступ к данным something из хранилища, но у него нет доступа к getSomething диспетчеризации getSomething. Аналогично, ChildComponent2 имеет доступ только к диспетчерскому действию getSomething но не к данным something. Это означает, что вы выставляете компоненты только на то, что им нужно из магазина.

Например, поскольку ChildComponent2 был передан в диспетчерское действие как getSomething, в моем onClick я могу вызвать this.props.getSomething и он вызовет диспетчерское действие без необходимости какого-либо доступа к хранилищу. Таким же образом он может продолжать передавать getSomething другому дочернему компоненту, и этот компонент может вызывать его и/или передавать его вниз, и цикл может продолжаться бесконечно.

class ChildComponent2 extends Component {

    render() {
        return (
            <div>
                <div onClick={this.props.getSomething}>Click me</div>
                <NestedComponent getSomething={this.props.getSomething} />
            </div>
        )
    }
}

Редактировать из комментариев

Хотя это не относится непосредственно к вопросу, в комментариях вы были немного смущены действиями. Я фактически не определял действие getSomething здесь. Вместо этого в приложениях Redux обычно все ваши определения действий помещаются в отдельный файл с именем actionCreators.js. Он содержит функции, которые называются так же, как ваши действия, и возвращают объект со свойством type и любые другие методы/данные, необходимые для действия. Например, вот очень простой пример файла actionCreators.js:

export function getSomething() {
    return {
        type: 'GET_SOMETHING',
        payload: {
            something: 'Here is some data'
        }
    }
}

Этот тип действия - то, что ваш редуктор будет слушать, чтобы узнать, какое действие было запущено.

Ответ 2

Если вы используете пакет react-redux, вы завершаете свои компоненты в Provider с помощью store prop. Это устанавливает ваше единственное хранилище в контексте React, которое затем получает доступ к методу connect в дочерних компонентах. Метод connect выполняет две функции (mapStateToProps и mapDispatchToProps), которые являются вашими крюками для получения состояния из хранилища и отправки сообщений.

Взгляните сюда для получения дополнительной информации