2017-05-30 79 views
2

我有一个持有公司和公司内部的对象,有一组团队。如何在推送对象内的阵列时避免突变

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' 
    } 
} 

当添加一个团队时,我使用这个reducer将团队推送到数组。

case types.ADD_TEAM_SUCCESS : 
    return Object.assign({}, state, state.teams.push(action.newTeam)); 

然而,这工作得很好,在控制台中我得到的是说一个警告:

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

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

回答

0

如前所述Object.assign()不会对对象执行深层克隆。

我的建议是正常化您的商店,并分成两个商店公司和团队。

比使用combineReducers并将其连接到一个商店,您将简化reducer并将使代码更具可读性。你也可以玩性能。

我的意思是......如果你将有组件与公司合作,你将在团队中有变化,你将避免容易重新渲染。

检查丹阿布拉莫夫篦视频教程 Redux: Normalizing the State Shape

我会做,不知怎的,(对不起,在打字稿代码)

​​
+0

谢谢你,我把公司分裂出队。这也将使修改团队变得更容易。 – Tom

0

问题是Object.assign()不会对您的对象[1]执行深层克隆(请参阅“Deep Clone的警告”)。

如果你没有在你的栈(如lodash),你可以使用JSON编码和解码工作做好任何工具库:

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

[1] https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign

+1

这是正确的,但作为一个更好的做法,考虑使用[combineReducers(HTTP: //redux.js.org/docs/api/combineReducers.html)只让一个reducer负责管理该州的分支“团队” – Faris

+0

这是很好的建议。 – Alp

+1

字符串化不是一个好习惯。你不想实际“深入克隆” - 你想嵌套_shallow克隆_。请参阅Redux文档关于[Structuring Reducers - 不可变更新模式](http://redux.js.org/docs/recipes/reducers/ImmutableUpdatePatterns.html)和[Redux关于深度克隆的常见问题解答](http:// redux .js.org /文档/常见问题/性能。html#performance-clone-state) – markerikson

3

See this link

如果使用ES2015,我可以这样做:

return Object.assign({}, state, { teams: [...state.teams, action.newTeam] });

您正在将对象直接推送到state.teams。你应该先制作一个副本,然后用它来代替。如果你不能使用spread运算符,你可以将state.teams分成一个新的变量并推送到它。