Redux 如何在将数组推入对象时避免突变

Redux 如何在将数组推入对象时避免突变,redux,react-redux,immutability,Redux,React Redux,Immutability,我有一个可以容纳一个公司的物体,在一个公司内部,有一系列的团队 company: { teams: [ { name: 'test team', description: 'dddd', team_manager: null, company: '592577d5b591966c8e535865', permalink: 'test-team', createdAt: '201

我有一个可以容纳一个公司的物体,在一个公司内部,有一系列的团队

  company: {
    teams: [
      {
        name: 'test team',
        description: 'dddd',
        team_manager: null,
        company: '592577d5b591966c8e535865',
        permalink: 'test-team',
        createdAt: '2017-05-30T07:38:58.983Z',
        updatedAt: '2017-05-30T07:38:58.983Z',
        id: '592d219277923054118e7299'
      }
    ],
    name: 'test company2',
    createdAt: '2017-05-24T12:08:53.418Z',
    updatedAt: '2017-05-24T12:08:53.419Z',
    id: '592577d5b591966c8e535865'
  }
}
当添加一个团队时,我使用这个缩减器将团队推到阵列中

case types.ADD_TEAM_SUCCESS :
  return Object.assign({}, state, state.teams.push(action.newTeam));
这很好,但是,在控制台中,我收到一条警告,上面写着:

'错误:在调度中检测到状态突变,路径为:
company.teams.0
'


关闭对象并将新团队推送到阵列的正确方法是什么?

问题在于
object.assign()
不会对对象进行深度克隆(请参阅“深度克隆警告”)

如果堆栈中没有任何实用程序库(如lodash),可以使用JSON编码和解码来完成工作:

case types.ADD_TEAM_SUCCESS:
    let stateCopy = JSON.parse(JSON.stringify(state));
    state.teams.push(action.newTeam);
    return state;
[1]

如果您正在使用es2015,我认为您可以执行以下操作:

返回Object.assign({},state,{teams:[…state.teams,action.newTeam]})


您正在将对象直接推送到
状态。团队
。你应该先复印一份,然后用它来代替。如果不能使用spread运算符,可以将state.teams分割成一个新变量,并推送到该变量

如前面所述,Object.assign()不会对对象进行深度克隆

我的建议是规范你的商店,并分为两个商店,一个是公司,一个是团队

与使用组合减缩器并将其连接到一个存储区相比,您将简化减缩器并使代码更具可读性。此外,你还可以比发挥性能

我是说。。。若你们将有一个组件只是和公司一起工作,你们将在团队中进行变更,你们将避免轻易地重新渲染

查看丹·阿布拉莫夫格栅视频教程

我会以某种方式做到这一点(很抱歉typescript中的代码)

导出接口ICompanyItem{
名称:字符串;
id:字符串;
createdAt:日期;
更新日期:日期;
}
导出接口ITeamItem{
id:字符串;
公司ID:字符串
名称:字符串;
描述:字符串;
团队经理:字符串;
createdAt:日期;
更新日期:日期;
}
导出接口ICompaniesState{
items:{[id:string]:ICompanyItem};
}
导出接口ITeamsState{
项:{[id:string]:ITeamItem};
}
导出常量组还原器:还原器=(状态:ITeamsState,操作:操作)=>{
if(isActionType(action,AddNewTeamItem)){
let itemsClone:{[id:string]:ITeamItem}={…state.items,[action.id]:action.team};
返回{
……国家,
项目:项目一
};
}
返回状态| |未加载状态;
};

这是正确的,但是作为一个更好的实践,考虑只使用一个减速机负责管理那个分支<代码>团队<代码>,这是一个很好的建议。严格化不是一个好的实践。你不想真正的“深层克隆”——你想做嵌套的浅层克隆。请参阅上的Redux docs部分和“谢谢你”,我将团队从公司中分离出来。这也将使修改团队变得更容易。
export interface ICompanyItem {    
    name: string;    
    id: string;
    createdAt: Date;
    updatedAt: Date;    
}

export interface ITeamItem {
    id: string;
    companyId: string
    name: string;
    description: string;
    team_manager: string;
    createdAt: Date;
    updatedAt: Date;
}

export interface ICompaniesState {
    items: { [id: string]: ICompanyItem };
}

export interface ITeamsState {
    items: { [id: string]: ITeamItem };
}


export const teamsReducer: Reducer<ITeamsState> = (state: ITeamsState, action: Action) => {

    if (isActionType(action, AddNewTeamItem)) {
        let itemsClone: { [id: string]: ITeamItem } = { ...state.items, [action.id]: action.team };

        return {
            ...state,
            items: itemsClone
        };
    }

    return state || unloadedState;
};