Developments in Digital
Developments in Digital

Using immutable with Redux

If you wish to use immutable with Redux, there is excellent coverage of good practices on the official Redux documentation. The general advice is to use a Higher Order Component (HOC) to convert the immutable js properties used in your container components, to plain JavaScript properties to be used in your presentational components.

For example:

import React, { Component } from 'react'
import { Iterable } from 'immutable'

const toJS = WrappedComponent => {
  return class ImmutableWrapper extends Component {
    constructor(props) {
      super(props)

      this.updateNewProps = this.updateNewProps.bind(this)
      this.newProps = this.updateNewProps(this.props)
    }

    updateNewProps(currentProps) {
      const objectEntries = Object.entries(currentProps)
      return objectEntries.reduce((newProps, entry) => {
        newProps[entry[0]] = Iterable.isIterable(entry[1])
          ? entry[1].toJS()
          : entry[1] // eslint-disable-line
        return newProps
      }, {})
    }

    componentWillReceiveProps(nextProps) {
      this.newProps = this.updateNewProps(nextProps)
    }

    render() {
      return <WrappedComponent {...this.newProps} />
    }
  }
}

export default toJS

However, you'll notice the use of Object.entries. There is an issue introduced in Chrome 65 which may surface as an error running your Redux application that uses the HOC approach when the code is minified, for example:

this.props.foo is not a function

The suggested fix in the short term is to avoid the use of Object.entries here, and use an equivalent alternative:

const entries = x => Object.keys(x).reduce((y, z) => y.push([z, x[z]]) && y, [])