简体   繁体   English

使用Redux / React在数组中移动项目

[英]Move item in array with Redux / React

I would like to know, how can I move an object in array with Redux. 我想知道,如何使用Redux移动数组中的对象。

In my reducer I have this : 在我的减速机中我有这个:

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)
};

My tree looks like that: 我的树看起来像那样:

buckets[
    blocks[
        messages[
            replies [
                {my_object},
                {my_object},
                {my_object},
                ...
            ]
        ]
    ]
]

I would like move the reply object in replies array, but with my code, I have no error but all replies are remove... 我想在回复数组中移动回复对象,但是使用我的代码,我没有错误,但所有回复都被删除...

There are several ways to deal with deeply nested data structures in Redux. 有几种方法可以处理Redux中深层嵌套的数据结构。 There's a good article in the redux docs about Normalizing State Shape which could help avoid this problem altogether. 关于规范化状态形状的redux文档中有一篇很好的文章可以帮助完全避免这个问题。

If flattening the state is not an option, I would recommend using a utility library to modify deeply nested objects. 如果不能选择展平状态,我建议使用实用程序库来修改深层嵌套对象。 My preference is ramda.js , but lodash etc. also contain this kind of functionality. 我的偏好是ramda.js ,但lodash等也包含这种功能。

With ramda, you can write reducers using "lenses" to change nested state without mutating the original state. 使用ramda,您可以使用“镜头”编写reducers来更改嵌套状态而不会改变原始状态。

Using ramda, your return expression could be written like this: 使用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,
)

I'm not sure if this exactly solves your problem, because your question does not include a minimal, complete and verifiable example , but I think it's pretty close to what you want. 我不确定这是否能完全解决您的问题,因为您的问题不包括最小,完整和可验证的示例 ,但我认为它非常接近您的需求。

If you don't like ramda's functional programming style, you might want to check out immer for a completely different approach to immutable state. 如果您不喜欢ramda的函数式编程风格,您可能需要查看immer以获得完全不同的不可变状态方法。

It is possible to rewrite your code without using an utility library, but it's very difficult to avoid bugs, and your code will be much harder to read. 可以在不使用实用程序库的情况下重写代码,但是很难避免错误,并且您的代码将更难以阅读。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM