Galivan
Galivan

Reputation: 5328

Modify selector in redux saga without mutating state

When using a selector, I thought that I could do whatever I wanted with the variable without modifying the state, so I was surprised that the state became mutated.

So if this is wrong (in a redux saga):

const filters = yield select(state => state.filters.filters);

filters.terms['helloo'] = "mutated";

//send data with request
yield put(requestData(filters)

How come that first line is a direct reference to the state?

Anyway, if I try using Object.assign, it also mutates state:

const filters = Object.assign({}, yield select(state => state.filters.filters));
filters.terms['helloo'] = "mutated";

How do I create a selection that is a copy of the state?

Upvotes: 3

Views: 1391

Answers (1)

markerikson
markerikson

Reputation: 67469

There's truly no "magic" involved here. Redux's getState() is literally just return state, and both hand-written selectors and Reselect return whatever you have written the functions to return. So, in that example, filters is the actual object reference that's nested inside the store state, because that's what your function returned.

Per the Redux docs page on "Immutable Update Patterns", you need to copy all levels of nesting that you want to update. In your example, you're making a copy of filters, but not filters.terms, so terms is also still the original object that's in the store. You would need to make a copy of that as well, and modify the copy.

Upvotes: 2

Related Questions