Reputation: 609
I have a problem. I have a simple Grid and the Grid gets its data from the redux state. But when I sort, I noticed that my data changes in the state, which it shouldn't or I missunderstood redux at this point. Here a bit of code
reducer:
const gridOptions = {
columns: ["id", "name", "lastname"],
data: [
{id: 1, name: "test", lastname: "test2"},
{id: 2, name: "test1", lastname: "test3"}
],
sortBy: {},
filter: {}
}
const rootReducer = combineReducers({
data: function (state = gridOptions.data, action) {
return [...state];
},
selectedRow: function (state = {}, action) {
switch (action.type) {
case "ROW_SELECTED":
return action.data
default:
return state
}
},
sortBy: function (state = gridOptions.sortBy, action) {
switch (action.type) {
case "SORT_CHANGE":
return Object.assign({}, action.column);
default:
return state;
}
},
columns: function (state = gridOptions.columns, action) {
return state;
},
filter: function (state = gridOptions.filter, action) {
return state;
}
})
const store = createStore(rootReducer);
the container component. I know it is a bit messy.
var mapStateToProps = (state) => {
return {
data: (() => {
if (!state.sortBy) {
return state.data
} else {
return state.data.sort()
}
})(),
selectedRow: state.selectedRow,
sortBy: state.sortBy
}
}
var mapDispatchToProps = (dispatch) => {
return {
onRowSelected: data => dispatch({type: "ROW_SELECTED", data}),
onSortChange: column => {
dispatch({type: "SORT_CHANGE", column})
},
onFilter: filterText => {
dispatch({type: "FILTER_CHANGE", filterText})
}
}
}
So now to the question. For some reason I don't understand ... if I console.log the state.data
...everytime it gets sorted, the state.data
gets mutated...which is not suppose to happen. But the real question is. why? Or do I missunderstand redux?
Upvotes: 0
Views: 89
Reputation: 17878
If you have a look at what .sort()
actually does it says
The sort() method sorts the elements of an array in place and returns the array
So your mapStateToProps
is actually mutating the state. There's nothing in redux that stops you from doing this, you have to take care of keeping the state immutable yourself.
This should be solved by using (for example)
return [...state.data].sort()
Or some other way to clone the array before sorting it.
You can replicate this in the browser console by running these two lines and comparing the output
var a = [2,1]; console.log(a.sort()); console.log(a)
var a = [2,1]; console.log([...a].sort()); console.log(a)
The first one will change the original array, the second will not.
Upvotes: 1