Обновить отдельную запись во вложенном объекте состояния, react-redux

Я работаю над структурой сетки, где пользователь может динамически добавлять разделы, подразделы или элементы. Я управляю этими вещами в моем объекте состояния redux. Пользовательский интерфейс моей сетки выглядит следующим образом:

введите здесь описание изображения

Я хочу обновить одну запись строки вместо того, чтобы снова перезагружать всю сетку. Для этого всякий раз, когда пользователь изменяет какое-либо значение ячейки строки, я вызываю update-row api, и в случае успеха я пытаюсь обновить это значение в редукторе, используя следующий код.

case UPDATE_ORDER_LINES_SUCCESS:
let stateData = state.get(`GridData`);
      const dataIndex = stateData.children.findIndex(
        (listing) => listing.id === action.row.id  // row id which is updated 
      );
      stateData[0].children[dataIndex] = action.row;
      let data = Object.assign(stateData, { children: stateData.children });
      state = state.set(`GridData`, [data]);

Этот код отлично работает для первого уровня дочерних записей (согласно объекту json), но проблема возникает, если пользователь обновляет значение дочерней записи n-го уровня. Как я могу обновить эту запись строки в моем состоянии redux?

Мой текущий образец состояния редукции:

    {
  "views": [
    {
      "id": "5e6b8961ba08180001a10bb6",
      "viewName": "house",
      "description": "house view",
      "name": "house",
      "children": [
        {
          "id": "5e6b8961ba08180001a10bb7",
          "viewName": "house",
          "sectionName": "Temporary",
          "sectionId": "SEC-02986",
          "description": "Temporary",
          "sequenceNumber": 4,
          "refrenceId": "SEC-02986",
          "children": [
            {
              "id": "5e590df71bbc71000118c109",
              "lineDescription": "AutoPickPack01",
              "lineAction": "Rent",
              "quantity": 5,
              "deliveryDate": "2020-02-29T06:00:00+11:00",
              "pickDate": "2020-02-28T06:00:00+11:00",
              "pickupDate": "2020-03-01T06:00:00+11:00",
              "prepDate": "2020-02-28T06:00:00+11:00",
              "returnDate": "2020-03-01T06:00:00+11:00",
              "shippingDate": "2020-02-29T06:00:00+11:00",
              "unitPrice": 7000,
              "children": [
                {
                  "id": "5e590df71bbc71000118c10a",
                  "orderId": "Ord-05788_1",
                  "lineNumber": "01a7b77c-792a-4edb-9b73-132440621968",
                  "purchaseOrderNumber": null,
                  "lineDescription": "29Janserial",
                  "lineAction": "Rent",
                  "quantity": 5,
                  "pricingMethod": "Fixed",
                  "displayUnit": "Days",
                  "unitPrice": 0,
                  "chargeAmount": 0,
                  "pickDate": "2020-02-17T06:00:00+11:00",
                  "prepDate": "2020-02-28T06:00:00+11:00",
                  "shippingDate": "2020-02-29T06:00:00+11:00",
                  "deliveryDate": "2020-02-29T06:00:00+11:00",
                  "pickupDate": "2020-03-01T06:00:00+11:00",
                  "returnDate": "2020-03-01T06:00:00+11:00",
                  "name": "29Janserial",
                  "description": "29Janserial",
                  "discountAmount": "",
                  "discountPrice": ""
                }
              ]
            }
          ]
        }
      ]
    }
  ]
}

Как лучше всего обновить данные вложенных дочерних строк в редукторе?


person Kd dev    schedule 15.04.2020    source источник
comment
Вы смогли найти решение? Пожалуйста, взгляни на мой ответ   -  person bsapaka    schedule 17.04.2020
comment
Привет @bsapaka спасибо   -  person Kd dev    schedule 20.04.2020


Ответы (2)


Поскольку redux не позволяет изменять текущее состояние и возвращать его обратно, трудно изменить вложенный дочерний элемент. Хотя крайне не рекомендуется иметь такую ​​вложенную структуру в redux, скорее, она должна быть нормализована, как ответил @bsapaka. Но если вы все еще хотите обновить вложенный объект и вернуть все состояние как неизменное, immer должен быть вашим другом. immerJS был настолько популярен для обработки неизменяемых состояний.

Установите иммер и редукс-иммер в свой корпус

yarn add immer redux-immer

В вашем reducers.js файле, где все редукторы были объединены с помощью combineReducers

import produce from 'immer';
import { combineReducers } from 'redux-immer';

// Replace your current combineReducers with
combineReducers(produce, { /* Object of all reducers */ });

В текущем файле редуктора

import product from 'immer';

const findNestedChild = (arr, itemId) => (
  arr.reduce((a, item) => {
    if (a) return a;
    if (item.id === itemId) return item;
    if (item['children']) return findItemNested(item['children'], itemId)
  }, null)
);

case UPDATE_ORDER_LINES_SUCCESS:
  return produce(state, draftState => {
    const { row: newChild, row: { id }} = action;
    let child = findNestedChild(draftState.views, id);
    child = newChild;
  });
person Manish Jangir    schedule 18.04.2020

Вы должны нормализовать свое состояние, которое сглаживает дерево, и объекты становятся связанными с помощью ссылок на идентификаторы вместо прямого вложения.

Например

{
  "entities": {
    "orders": {
      "o1": { "id": "o1", "productIds": ["p1", "p2"] },
      "o2": { "id": "o2", "productIds": ["p2", "p3"] },
      "o3": { "id": "o2", "productIds": ["p3"] }
    },
    "products": {
      "p1": { "id": "p1", "orderIds": ["o1"] },
      "p2": { "id": "p1", "orderIds": ["o1", "o2"] },
      "p3": { "id": "p1", "orderIds": ["o2", "o3"] }
    },
    "views": {
      "v1": { "id": "v1", "childIds": ["v1.1", "v1.2"] },
      "v1.1": { "id": "v1.1", "parentId": "v1" },
      "v1.2": { "id": "v1.2", "parentId": "v1" }}
  },
  "ids": {
    "orders": ["o1", "o2", "o3"],
    "products": ["p1", "p2", "p3"],
    "views": ["v1", "v1.1", "v1.2"]
  }
}

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

Redux docs по нормализации

Инструмент преобразования (де) нормализации

Библиотека утилит редуктора для управления нормализованным состоянием

person bsapaka    schedule 15.04.2020