我想知道,如何使用 Redux 移动数组中的对象。
在我的 reducer 中我有这个:
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},
...
]
]
]
]
我想移动回复数组中的回复对象,但使用我的代码,我没有错误,但所有回复都被删除...
最佳答案
Redux 中有多种处理深度嵌套数据结构的方法。 redux 文档中有一篇关于 Normalizing State Shape 的好文章这可以帮助完全避免这个问题。
如果无法扁平化状态,我建议使用实用程序库来修改深度嵌套的对象。我的偏好是ramda.js ,但是lodash等也包含这种功能。
使用 ramda,您可以使用“lenses”编写 reducer 来更改嵌套状态,而无需改变原始状态。
使用 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采用完全不同的方法来实现不可变状态。
可以在不使用实用程序库的情况下重写代码,但是很难避免错误,并且您的代码将更难以阅读。
关于javascript - 使用 Redux/React 移动数组中的项目,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56135357/