Реагировать с избыточным вложенным состоянием, работая с вложенными массивами - PullRequest
2 голосов
/ 21 мая 2019

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

(Работа с Azure) мое состояние выглядит следующим образом

Существует множество арендаторов. Каждый арендатор может иметь 1 или более подписок. Каждая подписка может иметь 1 или более групп ресурсов. Каждая группа ресурсов может иметь 1 или более ресурсов. Каждый ресурс может иметь 1 или более тегов.

выглядит примерно так:

    tenants: [
        {
            DisplayName: "blah",
            DomainName: "blah.onmicrosoft.com",
            TenantId: "72f988bf-1111-1111-1111-111111111111",
            active: false,
            subs: []
          },
          {
            DisplayName: "blah2",
            DomainName: "blah2.onmicrosoft.com",
            TenantId: "57aa6e76-1111-1111-1111-111111111111",
            active: true,
            subs: [
                {
                    subId: '444-555',
                    subName: 'SubName',
                    state: "enabled",
                    active: true,
                    resourceGroups: [
                        {
                            name:"one",
                            id: "/blah/123/456",
                            resources: [
                                {
                                    name: "vm1",
                                    type: "Microsoft.Compute/VirtualMachine"
                                },
                                {
                                    name: "vm2",
                                    type: "Microsoft.Compute/VirtualMachine"
                                }
                            ]
                        },
                        {
                            name:"two",
                            id: "/blah/555/222",
                            resources: [
                                {
                                    name: "vm3",
                                    type: "Microsoft.Compute/VirtualMachine"
                                },
                                {
                                    name: "vm4",
                                    type: "Microsoft.Compute/VirtualMachine"
                                }
                            ]
                        },
                    ]
                }

            ]
        }
    ]
}

Я изо всех сил пытаюсь понять, как отслеживать и изменять состояние для каждого элемента, например, показывать / не показывать в пользовательском интерфейсе, нажимать кнопки и т. Д. Так, например, если мне нужно вложенное меню, отслеживание того, что и не отображается и не отображается должным образом в зависимости от того, что щелкнуло и т. д., чтобы свернуть или развернуть данное меню. Так, например, если я нажимаю на кнопку / поле / заголовок «Арендатор», он сворачивает все дочерние элементы.

Я делаю функцию для каждого состояния «уровень глубины» и обхожу индексы? Так, например, если бы я хотел работать с виртуальной машиной и тегами, я бы передал индекс арендатора, субиндекс, индекс RG и т. д.? Я думаю, что это сработает, но звучит ужасно, ТБХ.

Или я каким-то образом разделил штат на несколько редукторов, возможно, один для арендаторов, один для субтитров и т. Д.? И сделать некоторые из ключевых ссылок в качестве государственной собственности, например. в редукторе resourceGroup есть ключ sub, который указывает на индекс подписки?

Любой совет или мысли о том, как справиться с этим, было бы замечательно. Спасибо.

edit: Я думал, что обновлю то, что в итоге сделал.

  • Стандартизирована модель состояния, поэтому каждый ресурс имеет одинаковые поля
  • «Нормализовано» / сглаживает состояние, поэтому оно состоит только из одного массива

Состояние теперь выглядит так:

resources: [
    {
        type: "tenant",
        displayName: "Microsoft",
        shortId: "72f988bf-1111-1111-1111-111111111111",
        longId: "/blah/123/456/789",            
        isVisible: false,            
        info: {
            active: false,
            domainName: "microsoft.onmicrosoft.com",
        },
        children: []
    },
    {
        type: "tenant",
        displayName: "blahdy blah blah",
        shortId: "57aa6e76-1111-1111-1111-111111111111",
        longId: "/blah/123/456",            
        isVisible: false,            
        info: {
            active: true,
            domainName: "blah.onmicrosoft.com",
        },
        children: [2, 7]
    },

    {
        type: "subscription",
        shortId: '444-55522',
        longId: "/blah/123/456/789",
        displayName: 'SubName',            
        isVisible: false,            
        info: {
            active: true,
            state: "enabled",
        },
        children: [3,4]
    }

]

Массив 'children' для каждого свойства является ссылкой на индекс, который является его «вложенным» дочерним элементом.

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

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

var ResourceWrapper = connect(mapStateToProps, mapDispatchToProps)(Resource);

export default ResourceWrapper;

Ответы [ 2 ]

1 голос
/ 21 мая 2019

Или я как-то разделил состояние на несколько редукторов, возможно, один для арендаторов, один для сабвуферов и т. Д.?

Конечно, вам нужно разделить состояние на несколько редукторов (т. Е. Принцип единой ответственности )

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

Таким образом, у вас есть tenants/subs/resourceGroups/resources древовидная структура и структура каталогов.Ваш формат действия также должен соответствовать структуре каталогов (т. Е. tenants/subs/add для добавления подписки на определенного арендатора или tenants/remove для удаления арендатора).Наличие этого формата будет полезно для фильтрации действий с использованием redux-dev-tools.

Таким образом, каждая папка имеет свой собственный редуктор, такой как tenants, где она просто обрабатывает «сегмент клиента» хранилища.Для клиента-арендатора он может обрабатывать связанные с арендатором действия пользовательского интерфейса, которые влияют на срез арендатора.

PS, имеющая структуру состояний, подобную ответу API, является преимуществом (в том смысле, что преобразование больше не требуется).

0 голосов
/ 21 мая 2019

Может быть, это поможет некоторым:

При создании приложений React и Redux обычно создается папка для каждого компонента в папке компонента. Каждая папка будет иметь файл Component.js вместе с component.action.js и component.reducer.js. Затем редукторы объединяются с использованием combReducers из пакета response-redux - мое соглашение заключается в том, чтобы поместить это в ту же папку, что и хранилище, куда оно затем передается, импортируется и передается в хранилище, которое затем передается в провайдера также из response-redux. , обертывающий компонент App: component.

Начальное состояние приложения объявлено как const initialState = {var1: value1, var2: value2}. Это передается в редуктор в качестве первого аргумента для установки начального состояния и действия в качестве второго аргумента: редуктор затрат = (state = initialState, action) => {…}.

Редукторы обычно являются оператором switch, который включает action.type. У действия будут другие переменные, которые вы указали в создателе действия. Редуктор возвращает новое состояние обычно action.someVariable. Соглашение, которое мне больше всего нравится делать так: return {… state, someVariable: ‘newValue’, anotherVariable: ‘anotherValue’}.

Вы бы справились с тем, показывает ли компонент переменную isVisible для этого компонента. Если у вас есть выпадающее меню в том же компоненте. Было бы действие и создатель действия. Экспортировать действие const TOGGLE_MENU = ‘TOGGLE_MENU‘ и экспортировать const toggleMenu = () => ({type: TOGGLE_MENU}); Редуктор при включении TOGGLE_MENU (который вы импортировали в редуктор) вернет {… state, isVisible:! State.isVisible}. Вы бы указали isVisible: false в initialState, который вы объявили выше редуктора.

...