Redux

To have a single point of truth for our data: the Redux state.

yarn add redux
yarn add react-redux

Event flow looks like:

  • A UI action is triggered by the user
  • This UI action generates and dispatches an action
  • This action is caught by Redux
  • The action is processed by the reducer
  • Redux state is updated
  • Impacted components are updated if their props depends on Redux state

Redux Higher order component: connect

import { connect } from 'react-redux';

// Articles list props depending on Redux state
const mapStateToProps = state => ({ entities: state.articles.list });

// Article list can trigger following events:
// - on component mounting, it "loads" articles which will update `state.articles.list`
// - on delete button click, it "deletes" the appropriate article
const mapDispatchToProps = dispatch => {
  return {
    load: () => dispatch(loadArticles()),
    delete: id => dispatch(deleteArticle(id))
  };
};

// Order matter. If only `mapDispatchToProps` is defined, `connect` requires a 
// `null` first argument
const ArticlesContainer = connect(
  mapStateToProps,
  mapDispatchToProps
)(ArticleList);

Reducers

The key used in combinedReducers is used to define keys in store. Given

combineReducers({
  article: articleReducer,
  catalog: catalogReducer
});

and for example, in catalog reducers, state is updated as:

export default function reducer(state = {}, action = {}) {
  return { ...state, list: catalogsList };
}

Catalogs list is not access via store.catalogs but store.catalogs.list. Articles list behave similarly

Ducks

Instead of splitting actions, action creators and reducers in three different files, they are merged in a single file:

Consequently, we can have the following folder structure:

  • src/redux/products/article.js: Article ducks
  • src/redux/products/catalog.js: Catalog ducks

Middleware

  • logging: https://redux.js.org/advanced/middleware#the-final-approach
  • API stuff: React-thunk or Saga