我想知道,如何使用Redux在数组中移动对象。
在我的减速器中,我有这个:
case SEQUENCES.MOVE_REPLY_ON_BLOCK :
indexBucket = action.indexBucket; // => 0
indexBlock = action.indexBlock; // => 0
indexReply = action.indexReply; // => 1
replySelected = action.payload.reply; // => my reply object
newIndex = action.payload.newIndex; // => 2
return {
...state,
buckets: state.buckets.map((bucket, i) => i === indexBucket ? {
...bucket,
blocks: bucket.blocks.map((block, i) => i === indexBlock ? {
...block,
messages: block.messages.map((message, i) => i === 0 ? {
...message,
replies: [
...state.buckets[indexBucket].blocks[indexBlock].messages[0].replies.splice(indexReply, 1),
...state.buckets[indexBucket].blocks[indexBlock].messages[0].replies.splice(newIndex, 0, replySelected)
]
} : message)
} : block)
} : bucket)
};
我的树看起来像这样:
buckets[
blocks[
messages[
replies [
{my_object},
{my_object},
{my_object},
...
]
]
]
]
我想将回复对象移动到replies数组中,但是使用我的代码,我没有错误,但是所有回复都已删除...
答案 0 :(得分:3)
在Redux中有几种处理深度嵌套数据结构的方法。 在redux文档中有一篇关于Normalizing State Shape的好文章,可以帮助您完全避免这个问题。
如果无法压平状态,我建议使用实用程序库来修改深层嵌套的对象。我的偏好是ramda.js,但lodash等也包含这种功能。
使用ramda,您可以使用“镜头”来编写化简器以更改嵌套状态,而无需更改原始状态。
使用ramda,您的返回表达式可以这样写:
// import * as R from 'ramda'
return R.over(
R.lensPath([
'buckets', action.indexBucket,
'blocks', action.indexBlock,
'messages', 0,
'replies',
]),
R.move(action.indexReply, action.payload.newIndex),
state,
)
我不确定这是否能完全解决您的问题,因为您的问题不包含minimal, complete and verifiable example,但我认为它与您想要的内容非常接近。
如果您不喜欢ramda的函数式编程风格,则可能需要查看immer以获取一种完全不同的不可变状态方法。
可以在不使用实用程序库的情况下重写代码,但是很难避免错误,并且代码很难阅读。