Migrating the Webapp to Redux

The Mattermost webapp is going through a big restructuring effort to move from using Flux and Redux. When we first started building the webapp, React was still new to the world, and so were the frameworks and design patterns. As a result, the webapp has had a lot of organic growth over the last couple of years, and is using an assortment of different design patterns.

This campaign is meant to help with that by moving app state and logic into our Redux repository, and by migrating the webapp components to be pure and use Redux to supply their props.

By completing this campaign, we’re looking to:

  • Reduce complexity of the webapp and consolidate into a single design pattern.
  • Increase webapp performance through pure components and selector memoization.
  • Share state related logic with other Mattermost clients such as the mobile apps.

Contributing

If you’re interested in contributing please join the Redux channel on pre-release.mattermost.com. Progress on moving individual components over to use Redux is tracked on this spreadsheet. If you want to work on one of the components let us know in the Redux channel or by making a comment on the spreadsheet.

List of contributors, in alphabetical order:

For guidance on migrating a webapp component to Redux, read the next section.

Component Migration Steps

There are a few steps involved with migrating a component to use Redux. Some of them may not apply to every component and they may change slightly based on the component you’re working on. In general, you can these steps as a checklist for work that needs to be done on each component.

  1. Move any PropTypes from the bottom of the file to be defined at the top of the component, as shown here.
  • Also replace any React.PropTypes usages with just PropTypes and add import PropTypes fron 'prop-types'; to the file imports.
  • Please make sure to add documentation for each prop, as shown in the above link.
  1. Switch the component to extend React.PureComponent instead of React.Component and remove the shouldComponentUpdate function if it exists.
  2. If the component imports any stores (ex. user_store.jsx), create a container by:
  1. Creating props to hold the data pulled from the stores.
  2. Following this guide and creating a folder and index.js for the component.
  3. Using selectors from Redux inside the container to fill the props of the component.
  1. Remove all store imports from the component.
  1. If the component imports any actions (ex. user_actions.jsx), then:
  1. Create an actions prop with each action as a child, similar to this.
  2. Use actions from Redux to fill the action props of the mapDispatchToProps function.
  1. Replace each action call to use the actions in the props (ex. this.props.actions.someAction()).
  2. Remove all action imports from the component.
  1. Move any other variables holding store state into props fed from Redux or parent components.
  2. Add component tests as described by this blog post and by following the example of other tests.

Examples

You can see some example pull requests here: