xoma2
@xoma2
Программист

Объясните простыми словами как работает Redux?

Объясните простыми словами. А то не до конца понимаю что к чему.
Хоть и сделал тестовое приложение по мануалу
  • Вопрос задан
  • 27411 просмотров
Пригласить эксперта
Ответы на вопрос 4
У вас есть одно большое дерево, в котором хранится все состояние (state) приложения - это хранилище (store).
Также у вас есть набор редьюсеров (которые скомбинированы в один общий rootReducer) - это функции, который принимают текущее состояние и действие и возвращают новое состояние:
function someReducer(state = initialState, action) {
  // обычно выглядит как switch 
  // action - простой js-объект
  //              и обязательно имеет строковое поле type
  switch(action.type) {
    // обрабатываем действие с типом SOME_ACTION_NAME
    case 'SOME_ACTION_NAME':
      // берем какие-то данные из экшена и возвращаем новое состояние
      // при этом менять sate нельзя!
      // state.someProperty = action.newStateData <--- НЕТ!
      return { ...state, action.newStateData };
    // Если мы не обрабатываем действие - просто возвращаем старое состояние
    default:
      return state;
  }
}


Также есть экшен креаторы (actionCreators) - это функции, которые возвращают действие. затем это действие вещается в хранилище (диспатчится). Типичный пример:
function someActionCreator(someArg) {
  return {
    type: 'SOME_ACTION_NAME',
    newStateData: someArg + 5, // <-- разная логика
  };
}


По-умолчанию в качестве экшена мы можем вернуть только простой объект, но при создании хранилища можно добавить так называемый middleWare. Это специальные функции, которые принимают все экшены из диспатча и могут передавать их дальше (при этом содержат дополнительную логику).

Если мы хотим получить доступ к состоянию в экшен креаторе - воспользуемся thunkMiddleware:
import thunkMiddleware from 'redux-thunk';

function createStore(initialState) {
  const reducer = combineReducers(reducers);
  const finalCreateStore = applyMiddleware(
    thunkMiddleware // <-- добавляем middleware
  )(defaultCreateStore);
  return finalCreateStore(reducer, initialState);
}


Теперь мы можем делать так:
function someActionCreator(someArg) {
  return (dispatch, getState) => { // <-- возвращаем фукнцию, а не объект!
    const someState = getState().reducerName;
    return {
      type: 'SOME_ACTION_NAME',
      newStateData: someArg + someState, 
    };
  };
}


В общем схема выглядит так:

actionCreator --action--> dispatch --action--> middleware --action--> store --action--> reducer --> newState


Затем мы берем из react-redux метод connect, который подключает Ваш умный компонент к хранилищу:
import { connect } from 'react-redux';
import { bindActionCreators } from 'redux';

class MyComponent extends Component {
  static propTypes = {
    someProp: PropTypes.string.isRequired,
    someFunc: PropTypes.func.isRequired,
  };
}

// Тут мы берем из глобального состояния необходимую нам часть
// В ownProps - свойства компонента. Тут могут быть например свойства от роутера
function mapStateToProps(state, ownProps) {
  return {
    someProp: state.someReducer,
  };
}

function mapActionsToProps(dispatch) {
  return bindActionCreators ({ // <-- биндим все на disptach для удобства
    someFunc: (someArg) => someActionCreator(someArg + 1),
  }, dispatch);
}

export default connect(
  mapStateToProps,
  mapActionsToProps
)(MyComponent);
Ответ написан
Laiff
@Laiff
Front-end developer
Отличный мануал от самого Дани https://egghead.io/series/getting-started-with-redux
Документация переведенная на русский https://github.com/rajdee/redux-in-russian там почти все есть.
Есть еще приятная статья на хабре чисто по базовым принципам, но в некоторых местах не полная habrahabr.ru/post/269831
Ответ написан
@mistbow
Мне вот это очень помогло, особенно картинки внизу...
https://medium.com/russian/a-cartoon-intro-to-redu...
Ответ написан
Комментировать
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы