Как правильно обновить состояние редукции в редукторе ReactJS? - PullRequest
0 голосов
/ 11 февраля 2019

У меня есть следующая структура в моем хранилище данных Redux:

{
    filterData: {
        22421: {
            filterId: 22421,
            selectedFilters: [
                {
                    filterName: 'gender',
                    text: 'Male',
                    value: 'male'
                },
                {
                    filterName: 'gender',
                    text: 'female',
                    value: 'female'
                }
            ] 
        }   
        22422: {
            filterId: 22422,
            selectedFilters: [
                {
                    filterName: 'colour',
                    text: 'Blue',
                    value: 'blue'
                },
                {
                    filterName: 'animal',
                    text: 'sheep',
                    value: 'Sheep'
                }
            ] 
        }   

Может кто-нибудь указать мне на правильный путь обновления массива selectedFilters без непосредственного изменения состояния?т.е. как я могу добавить / удалить элементы в массиве selectedFilters для данного идентификатора фильтра?

Ответы [ 2 ]

0 голосов
/ 11 февраля 2019

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

Я считаю, что эта библиотека проще использовать , чем Immutable.js (и размер пакета будет меньше)

0 голосов
/ 11 февраля 2019

Как правило, это делается с использованием не изменяющих (т.е. возвращающих новый объект, а не изменяющих существующий) операторов и функций:

Вы должны делать это на каждом уровне, ведущем к последнему - где происходят ваши изменения.В вашем случае, если вы хотите изменить selectedFilters на одном из этих объектов, вам нужно будет сделать что-то вроде этого:

// Assuming you're inside a reducer function.
case SOME_ACTION:
  // Returning the new state object, since there's a change inside.
  return {
    // Prepend old values of the state to this new object.
    ...state,

    // Create a new value for the filters property,
    // since—again—there's a change inside.
    filterData: {
      // Once again, copy all the old values of the filters property…
      ...state.filters,

      // … and create a new value for the filter you want to edit.
      // This one will be about removal of the filter.
      22421: {
        // Here we go again with the copy of the previous value.
        ...state.filters[22421],

        // Since it's an array and we want to remove a value,
        // the filter method will work the best.
        selectedFilters: 
          state.filters[22421].selectedFilters.filter(
            // Let's say you're removing a filter by its name and the name
            // that needs to be removed comes from the action's payload.
            selectedFilter => selectedFilter.name !== action.payload
          )
      },
      // This one could be about addition of a new filter.
      22422: {
        ...state.filters[22422],

        // Spread works best for additions. It returns a new array
        // with the old values being placed inside a new one.
        selectedFilters: [
           // You know the drill.
          ...state.filters[22422].selectedFilters,

          // Add this new filter object to the new array of filters.
          {
            filterName: 'SomeName',
            text: 'some text',
            value: action.value // Let's say the value comes form the action.
          }
        ]
      },
    }
  }

Эта константа «копировать старые значения» необходима, чтобы убедиться, чтозначения из вложенных объектов сохраняются, поскольку оператор распространения копирует свойства поверхностно.

const someObj = {a: {b: 10}, c: 20}
const modifiedObj = {...someObj, a: {d: 30}}
// modifiedObj is {a: {d: 30}, c: 20}, instead of
// {a: {b: 10, d: 30}, c: 20} if spread created a deep copy.

Как видите, это немного обыденно.Одним из решений этой проблемы было бы создание неких вложенных функций-редукторов, которые будут работать на отдельных деревьях состояния.Тем не менее, иногда лучше не заново изобретать устройство и использовать уже имеющиеся инструменты, которые были созданы для решения подобных проблем.Как Immutable.js .

...