且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

国家不应该是不可变的吗?

更新时间:2023-01-01 09:43:35

你的责任不是这样做,而是只以不可变的方式改变 reducer 中的状态.如果您想确保防止这种突变,您可能需要查看 ngrx-store-freeze、Immutable 或类似...

通常,您会在开发期间使用 store-freeze 以确保您的代码中的任何地方(无论是组件还是减速器)都没有任何更改,然后在生产中将其关闭.>

I have the folling code:

reducer:

export function testReducer(state = [], action:TestActions):any[] {
    switch (action.type) {
        case TestAction1Success: {
            return [...action.payload];
        }
        case TestAction2Success: {
            return [ ...state, action.payload ];
        }
        case TestAction3Success: {

            const list = state.map(x => {
                if(x.id === action.payload.id){
                    return action.payload
                }
                return x;
            })

            return [ ...list ];
        }
        default: {
          return state;
        }
    }
}

component:

  ngOnInit() {
    this.store.dispatch(new TestAction1()); // Fill store
    this.list$ = this.store.select(selectList)
  }

  // this is a click binding to each element of this.list$ in the view
  edit(listItem) {
    listItem.name = "ASDASDASD" // this line also change the value in store if any action is called after this
    this.store.dispatch(new TestAction2(listItem)); 
  }

This changes the store even though only "SuccessActions" are queried in the reducer. I can see why the state is changing. It is because the default value of the state is always given in the reducer. But shouldn't it be immutalbe, if i change a value from a subscribtion of a store?

its pretty much your responsibility not to do it but to change state only in reducers in an immutable way. if you want to make sure this kind of mutation is prevented, you might want to take a look at ngrx-store-freeze, Immutable or similar...

usually, you would use store-freeze during development to ensure you don't have any mutations anywhere in your code (be it components or reducers) and then turn it off in production.