Redux Bad Practices: New Objects On The Fly
Adam Klein
Last updated on Dec 5, 2017

Consider the following code:

mapStateToProps = (state) => ({
  currentUser: {
    id: state.currentUserId,
    role: state.currentRole
  }
})

The example above will always return a new object for currentUser, and will force the component to re-render. The same idea applies to returning a new array (e.g. by using map, filter, concat), and anonymous functions.

Either pass the id and role as flat properties:

mapStateToProps = (state) => ({
  currentUserId: state.currentUserId,
  currentUserRole: state.currentRole
})

Or use a selector that returns currentUser from state:

mapStateToProps = (state) => ({
  currentUser: selectCurrentUser(state) // returns an object
})

Notice that passing an anonymous function will also create a new reference. So try to avoid code like this if you need a performant component:

<MyComp onEvent={ () => this.doSomething() } otherProps={ ... }/>

The () => doSomething() anonymous function will have a different reference each time we render MyComp, and will cause it to re-render even if it's a pure component (a component that re-renders only when state or props change).

Alternatively, you should pass a pre-binded function that is only initialized once:

bindedEventCallback = () => {}

render() {
  return <MyComp onEvent={ this.bindedEventCallback } otherProps={ ... }/>
}
Back to all articles

© 500Tech. Building high-quality software since 2012.