Immutable Redux
In this lesson, we will use Immutable.js in our Weather app that's created using React and Redux
we make the initial state in our reducer an immutable object by using the fromJS
function! We simply wrap the object that we assign to initialState
in fromJS
like so:
// reducer.js
/* … */
import { fromJS } from 'immutable';
var initialState = fromJS({
/* … */
});
/* … */
Now we need to rework our reducer. Since our state is now immutable, instead of doing Object.assign({}, state, { /* … */ })
everywhere we can simply use state.set
!
Let’s showcase this on the CHANGE_LOCATION
action. This is what our reducer looks like right now:
case 'CHANGE_LOCATION':
return Object.assign({}, state, {
location: action.location
});
Instead of doing this whole assigning business, we can simply return state.set('location', action.location)
!
case 'CHANGE_LOCATION':
return state.set('location', action.location);
Not only is that a lot cleaner, it’s also forcing us to work immutably, which means we can’t accidentally mess something up and introduce weird bugs! 🎉
Let’s do the same thing for our SET_DATA
, SET_DATES
and SET_TEMPS
cases:
case 'SET_DATA':
return Object.assign({}, state, {
data: action.data
});
case 'SET_DATES':
return Object.assign({}, state, {
dates: action.dates
});
case 'SET_TEMPS':
return Object.assign({}, state, {
temps: action.temps
});
This whole block becomes:
case 'SET_DATA':
return state.set('data', fromJS(action.data));
case 'SET_DATES':
return state.set('dates', fromJS(action.dates));
case 'SET_TEMPS':
return state.set('temps', fromJS(action.temps));
Isn’t that nice? Now, here’s the last trickery in our reducer, because what do we do for SET_SELECTED_TEMP
and SET_SELECTED_DATE
? How do we set state.selected.temp
?
It turns out Immutable provides us with a really nice function for that called setIn
. We can use setIn
to set a nested property by passing in an array of keys we want to iterate through! Let’s take a look at that for our SET_SELECTED_DATE
.
This is what it currently looks like:
case 'SET_SELECTED_DATE':
return Object.assign({}, state, {
selected: {
date: action.date,
temp: state.selected.temp
}
});
This works, but you have to agree it’s not very nice. With setIn
, we can simply replace this entire call with this short form:
case 'SET_SELECTED_DATE':
return state.setIn(['selected', 'date'], action.date);
So beautiful! Let’s do the same thing for SET_SELECTED_TEMP
and we’re done here!
case 'SET_SELECTED_TEMP':
return Object.assign({}, state, {
selected: {
date: state.selected.date,
temp: action.temp
}
});
becomes
case 'SET_SELECTED_TEMP':
return state.setIn(['selected', 'temp'], action.temp);
This is what our reducer looks like finally (let’s try running our weather app with our new reducer):
Get hands-on with 1400+ tech skills courses.