Переместить элемент в массив с помощью Redux / React - PullRequest
1 голос
/ 14 мая 2019

Я хотел бы знать, как я могу переместить объект в массиве с 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},
                ...
            ]
        ]
    ]
]

Я хотел бы переместить объект ответа в массиве ответов, но с моим кодом у меня нет ошибок, но все ответы удалены ...

1 Ответ

3 голосов
/ 14 мая 2019

Существует несколько способов работы с глубоко вложенными структурами данных в Redux.В документации к редуксу есть хорошая статья о нормализации формы состояния , которая может помочь избежать этой проблемы в целом.

Если выравнивание состояния не является вариантом, я бы порекомендовал использовать служебную библиотеку для измененияглубоко вложенные объекты.Я предпочитаю 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,
)

Я не уверен, что это точно решит вашу проблему, потому что ваш вопрос не включает минимальный, полный и проверяемый пример , но я думаю, что он довольно близок к тому, что вы хотите.

Если вам не нравится стиль функционального программирования ramda, вы можете проверить immer для совершенно другого подхода к неизменяемому состоянию.

Возможно переписать ваш код без использования служебной библиотеки, но очень трудно избежать ошибок, и ваш код будет намного сложнее читать.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...