I have an ApplicationState
which has project
member and my ProjectState
is something like this:
interface ProjectState {
listObjs: SomeType[];
}
In my component.ts
onInit I have something like this:
...
this.objID = someString
...
this.listObj$ =
this.store.select( state => state.project.listObjs.find( item => item.id === this.objID));
...
In my reducer I am handling creation of new state like this:
...
case (action.ACTION1): {
const newState = {... state};
const objIndex = state.listObjs.findIndex( item => item.id === action.payload.id )
if ( objIndex === -1 ) {
return state;
}
Object.assign(newState.listObjs[objIndex].someMember, {... action.payload.someData});
return newState;
}
...
I subscribed to listObj$
in my component onInit, but it gets served when initializing and whenever I make changes to obj
in array I don't see the subscribe
getting updated data
This is "direct" state mutation.
The spread operator (...
) does not clone recursive and Object.assign
mutates newState.listObjs[objIndex].someMember
.
You can install ngrx-store-freeze or enable the runtime checks in ngrx v8, and you'll get an error that you can't modify the state like this.
To solve this issue, you'll have to create a new state in an immutable way, or use immer. Clean NgRx reducers using Immer