Looking for react-redux Answers? Try Ask4KnowledgeBase
Looking for react-redux Keywords? Try Ask4Keywords

react-reduxНачало работы с реакцией-редукцией


замечания

React Redux - это библиотека, которая предоставляет привязки React для Redux.

Реагирующие компоненты, которые знают о магазине Redux, называются «Контейнеры», «Интеллектуальные компоненты» или «Компонент высшего порядка» (HOC). Такие компоненты, чтобы использовать Redux, должны:

  • Подпишитесь на магазин, чтобы получать обновления от магазина Redux
  • Отправка

Выполнение этого вручную подразумевает использование store.subscribe и store.dispatch(action) в контейнерах React.

React Redux упрощает привязку между хранилищем Redux и компонентом контейнера React с помощью функции connect , которая отображает свойства состояния Redux и создателей Action к реквизитам компонента.

connect - это функция, которая создает компонент более высокого порядка. Connect принимает 3 функции ( mapStateToProps , mapDispatchToProps , mergeProps ) и возвращает компонент контейнера, который обертывает исходный компонент, чтобы превратить его в «подключенный» компонент:

import { connect } from 'react-redux';

const Customers = { ... };
const mapStateToProps = (state) => { ... }
const mapDispatchToProps = (dispatch) => { ... }

export default connect(mapStateToProps, mapDispatchToProps)(Customers);

Подробный пример приведен в разделе примеров.

Поскольку всем компонентам контейнера необходимо получить доступ к хранилищу Redux, рекомендуется использовать специальный компонент <Provider> React Redux, который передает хранилище всем дочерним компонентам (внутренне используя контекст React).

Официальная документация: http://redux.js.org/docs/basics/UsageWithReact.html

GitHub repo: https://github.com/reactjs/react-redux

Версии

Версия Дата выхода
5.0.3 2017-02-23
5.0.2 2017-01-11
5.0.1 2016-12-14
5.0.0 2016-12-14
4.4.6 2016-11-14
4.4.5 2016-04-14
4.4.4 2016-04-13
4.4.3 2016-04-12
4.4.0 2016-02-06
4.3.0 2016-02-05
4.2.0 2016-02-01
4.1.0 2016-01-28
4.0.0 2015-10-15
3.0.0 2015-09-24
2.0.0 2015-09-01
1.0.0 2015-08-24
0.5.0 2015-08-07
0.1.0 2015-07-12

Полный пример

Предположим, у нас есть контейнер «CustomersContainer», который соединяет немой компонент «Клиенты» с магазином Redux.

В index.js:

import { Component }, React from 'react';
import { render } from 'react-dom';
import { Provider } from 'react-redux';
import { createStore } from 'redux';
import rootReducer from './redux/rootReducer';
import CustomersContainer from './containers/CustomersContainer';

let store = createStore(rootReducer);

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

В CustomerContainer:

import React, { Component } from 'react';
import { connect } from 'react-redux';

// Import action creators
import { fetchCustomers } from '../redux/actions';

// Import dumb component
import Customers from '../components/Customers';

// ES6 class declaration
class CustomersContainer extends Component {
  componentWillMount() {
    // Action fetchCustomers mapped to prop fetchCustomers
    this.props.fetchCustomers();
  }

  render() {
    return <Customers customers={this.props.customers} />;
  }
}

function mapStateToProps(state) {
  return {
    customers: state.customers
  };
}

// Here we use the shorthand notation for mapDispatchToProps
// it can be used when the props and action creators have the same name 
const CustomersContainer = connect(mapStateToProps, { fetchCustomers })(CustomersContainer);

export default CustomersContainer;
 

Hello World использует React Redux

В этом руководстве предполагается, что вы уже установили react , redux , react-router и react-redux и настроили react , redux и react-router . Если вы этого не сделали, пожалуйста, сделайте это.

Примечание. В то время как react-router не зависит от react-redux , очень вероятно, что мы будем использовать его в нашем реагирующем приложении для маршрутизации, и это позволяет нам очень легко использовать реакцию-редукцию.


FILENAME: app.js

'use strict';

import React from 'react';
import { render } from 'react-dom';
import { Router, Route, Link, browserHistory, IndexRoute } from 'react-router';
import { Provider } from 'react-redux';
import store from './stores';

render(
  (
    <Provider store={ store }>
      <Router history={ browserHistory }>
        {/* all the routes here */}
      </Router>
    </Provider>
  ),
  document.getElementById('app')
);
 

Этот файл будет иметь смысл для большинства из вас. То, что мы делаем здесь, - это получение магазина из ./stores и передача его на все маршруты с использованием Provider компонентов более высокого порядка, предоставляемого ./stores react-redux .

Это делает магазин доступным во всем нашем приложении.


Теперь давайте рассмотрим этот сценарий . У нас есть компонент UserComponent который получает данные от редуктора user и имеет кнопку, которая при нажатии обновляет данные в магазине.

Структура приложения

У нашего rootReducer есть user редуктор

const rootReducer = combineReducers({
    user: userReducer,
})
export default rootReducer;
 

Наш userReducer выглядит так

const default_state = {
  users: [],
  current_user: {
    name: 'John Doe',
    email: 'john.doe@gmail.com',
    gender: 'Male'
  },
  etc: {}
};

function userReducer( state=default_state, action ) {

  if ( action.type === "UPDATE_CURRENT_USER_DATA" ) {
    return Object.assign( {}, state, { current_user: Object.assign( {}, state.current_user, { [action.payload.field]: action.payload.value } ) } );
  }
  else {
    return state;
  }

}

export default userReducer;
 

И наш файл actions выглядит примерно так

export function updateCurrentUserData( data ) {
  return {
    type: "UPDATE_CURRENT_USER_DATA",
    payload: data
  }
}
 

Наконец, Давайте работать над нашим компонентом

FILENAME: UserComponent.js

'use strict';

import React from 'react';
import { connect } from 'react-redux';
import * as Action from './actions';

let UserComponent = (props) => {

  let changeUserDetails = (field, value) => {
    // do nothing
  }

  return(
    <div>
      <h1>Hello { props.current_user.name }</h1>
      <p>Your email address is { props.current_user.email }</p>
      <div style={{ marginTop: 30 }}>
        <button onClick={ () => { changeUserDetails('name', 'Jame Smith') } }>Change Name</button>
        <button onClick={ () => { changeUserDetails('email', 'jane@gmail.com') } }>Change Email Address</button>
      </div>
    </div>
  )

}

export default UserComponent;
 

Конечно, это не сработает , поскольку мы еще не подключили его к магазину.

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

Метод connect обеспечиваемый react-redux принимает три параметра

mapStateToProps , mapDispatchToProps и сам компонент .

connect( mapStateToProps, mapDispatchToProps )(Component)


Давайте добавим подключение к нашему компоненту UserComponent вместе с mapStateToProps и mapDispatchToProps

И давайте также обновить нашу функцию changeUserDetails, поэтому при вызове, он будет dispatch в action наших reducers , и на основе типа действия нашего редуктора будет ударом и внести изменения в хранилище, и после того , как магазин обновленного react-redux будет повторно -подготовьте наш компонент с новыми данными.

Звучит сложно? Это действительно не так.

Наш UserComponent.js будет выглядеть так:

'use strict';

import React from 'react';
import { connect } from 'react-redux';
import * as Action from './actions';

const mapStateToProps = ( state, ownProps ) => {
  return {
    current_user: state.user.current_user,
  }
}

const mapDispatchToProps = ( dispatch, ownProps ) => {
  return {
    updateCurrentUserData: (payload) => dispatch( Action.updateCurrentUserData(payload) ),
  }
}


let UserComponent = (props) => {

  let changeUserDetails = (field, value) => {
    props.updateCurrentUserData({ field: field, value: value });
  }

  return(
    <div>
      <h1>Hello { props.current_user.name }</h1>
      <p>Your email address is { props.current_user.email }</p>
      <div style={{ marginTop: 30 }}>
        <button onClick={ () => { changeUserDetails('name', 'Jame Smith') } }>Change Name</button>
        <button onClick={ () => { changeUserDetails('email', 'jane@gmail.com') } }>Change Email Address</button>
      </div>
    </div>
  )

}

const ConnectedUserComponent = connect(
  mapStateToProps,
  mapDispatchToProps
)(UserComponent)

export default ConnectedUserComponent;
 

Добавлено то, что мы здесь сделали

  • mapStateToProps : Это позволяет нам получать данные из хранилища и когда эти данные меняются, наш компонент будет повторно представлен с новыми данными.

    Наш компонент будет только повторно отображать, если данные нашего компонента запрашивают изменения в хранилище, а не когда какие-либо другие данные изменяются в магазине.

  • mapDispatchToProps : Это позволяет нам dispatch actions ко всем редукторам из нашего компонента .. (может быть любой компонент). И в зависимости от type действия наш userReducer запустит и вернет новое состояние с обновленными данными.

  • ConnectedUserComponent : Наконец, мы подключили наш компонент к хранилищу с помощью метода connect , передав все параметры и exported подключенный компонент.

  • Мы также обновили нашу функцию changeUserDetails, чтобы вызвать method на реквизитах, а также передать данные. И props в свою очередь, отправляют метод, который мы вызывали для всех редукторов.


НОТА:

  • Если мы не вернем новое состояние из редуктора, react-redux переделает наш компонент.

Установка или настройка

Использование redux непосредственно с react может показаться немного трудным. Что касается каждого component вы хотите обновить при изменениях в магазине, вам нужно подписаться на этот компонент в redux store

React Redux заботится обо всех этих проблемах и позволяет легко писать компоненты, которые могут запрашивать redux store данные из redux store и получать уведомление только после изменения этих данных. Это позволяет нам писать действительно эффективные компоненты.

Для установки react-redux все, что вам нужно сделать, это запустить эту команду npm

npm install --save react-redux
 

И вы сделали.


Примечание: React Redux зависит от

  • Реагировать (версия 0.14 или новее) и
  • Redux