Blog

Here we share our experiences, ideas, tips, and thoughts on React, Angular, Industry in general, and some other things.

Later Ctrl + ↑

Redux Bad Practices: Duplicate Code

Adam Klein

Many applications have repeating functionality for different reducers with minor changes. For example, many forms that have view and edit modes.

bad approach would be to duplicate the reducer code:

function userFormReducer(state, action) {
  switch (action.type) {
    case SET_USER_VIEW_MODE:
       return { ...state, viewMode: action.payload.viewMode };
    ...
  }
}

function jobFormReducer(state, action) {
  switch (action.type) {
    case SET_JOB_VIEW_MODE:
       return { ...state, viewMode: action.payload.viewMode };
    ...
  }
}

function companyFormReducer(state, action) {
  // you get the point...
}

good approach would be to delegate the work to a dedicated reducer, that saves viewMode per form name:

function formReducer(state, action) {
  switch (action.type) {
    case SET_VIEW_MODE:
       return {
         ...state,
         [action.payload.formName]: { viewMode: action.payload.viewMode }
       };
    ...
  }
}

There are a few patterns for doing this:

  • Extract repeated reducer logic to a dedicated reducer like in the example above;
  • Use a higher-order reducer for similar reducer functionality;
  • Use middleware if your use-case justifies that. For example, if you repeat similar code for many types of actions.

Keep it DRY (don’t repeat yourself). Taking the time to think how to re-use code, almost always proves to be efficient in the long run. Don’t be lazy, it’s worth the while!

Redux Bad Practices: Nested State

Adam Klein

Complex applications usually deal with data structures that have associations, e. g. posts that have comments.

bad approach would be to save the data nested in the state:

posts:
  id: 1
  title: 'Better Redux'
  comments:
    id: 2
    text: 'Great article!'

good approach would be to flatten the state and operate with foreign IDs on the data.

posts:
  id: 1
  title: 'Better Redux'
comments:
  id: 2
  postId: 1
  text: 'Great article!'

There are multiple disadvantages of storing a nested state.

Nested data structures are harder to maintain and explore. Nesting doesn’t allow for sharing associated models (many to many), for example comments can be on posts, and on images.

It’s easier to gain good performance with flat state, because the optimization works on comparing references. Changing a nested comment will force the change of the entire post object.

It’s also harder to find a nested object by ID; you’ll need to pass around the full path to the object.

And last but not least, it’s easier to debug the state when it’s fairly flat.

Robert C. Martin on Effective Estimation

Ilya Gelman

Estimating projects and tasks in something that many developers have to do all the time. No matter how many times we do that, giving perfect estimates is always hard or close to impossible.

Famous Robert C. Martin (uncle Bob) talks at YOW! 2016 on how to actually estimate projects without lying. This talk is important not just for developers, but also for many project managers.

On Thursdays we post videos that we believe are worth watching and that can make you a better front-end developer. Have such a video to share? Share with us

Redux Bad Practices: Duplicate State

Adam Klein

Let’s say you need to display a filtered list of products.

bad approach would be to save the filtered list on each filter change in a component’s state or in a different key in a Redux store.

onFilterChange(filter) {
  this.setState({
    filteredProducts: this.props.products.filter(...)
  })
}

good approach would be to use cached selectors with reselect:

mapStateToProps = (state) => ({
  filteredProducts: filteredProductsSelector(state)
})

Or calculate the computed data on render if it’s not shared and runs fast:

render() {
  const filteredProducts = this.props.products.filter(...);

  return <div>{ filteredProducts.map(...) }</div>;
}

Redux offers you a mechanism for a single source of truth. If you save different representations of the same data in your store or in component’s state you are violating that principal. You should only save raw data once, and calculate everything that can be derived from it.

Earlier Ctrl + ↓