redux: установить состояние в листовом узле большого дерева состояний - PullRequest
0 голосов
/ 12 апреля 2020

У меня есть неизменяемый объект, который содержит другие неизменяемые объекты, и дерево состояний избыточности установлено как экземпляр самого верхнего объекта:

records.js:

const TypeC = newRecord({
    content: null
})

const TypeB = newRecord({
    typeC: new TypeC;
})

export const TypeA = newRecord({
    typeB: new TypeB;
})

reducer.js:

import {
    TypeA,
} from './records';
import types from './types';

const applicationReducer = (state = new TypeA(), action) => {
    switch (action.type) {
    ...    
    }
    default:
        return state;
    }
};

Мой вопрос: как мне написать код редуктора для изменения поля content в Типе C? Я пробовал что-то вроде

CASE types.UPDATECONTENT: {
    return state.get('typeB').get('typeC').set('content', "new content")
}

, но, похоже, это возвращает только сегмент TypeC моего дерева состояний, когда мне нужно все дерево из root.

Ответы [ 2 ]

0 голосов
/ 11 мая 2020

state.get('typeB').get('typeC').set('content', "new content") спускается по дереву и изменяет атрибут «content» типа C. Но поскольку неизменным является неизменным , он ничего не изменяет, возвращает новую запись с обновленным значением (!). Вещи между state и 'type C' не затрагиваются. Кроме того, set возвращает вновь созданную запись, поэтому вы фактически перезаписываете state обновленным typeC.

. Простой способ обновить вложенные объекты - использовать "глубокие постоянные изменения", которые называются <operation>In, например setIn. Он также заботится о создании обновленных промежуточных объектов.

TL / DR:

CASE types.UPDATECONTENT: {
  return state.setIn(['typeB', 'typeC','content'], "new content");
}
0 голосов
/ 12 апреля 2020

Шаблон для вложенных объектов объяснен здесь:

https://redux.js.org/recipes/structuring-reducers/immutable-update-patterns/

...