构建react / redux应用程序的状态

时间:2016-03-04 20:21:16

标签: javascript reactjs redux react-redux

我正在努力构建一个React / Redux应用程序 - 我列出了我为解决方案尝试的选项的问题,但没有“感觉正确”,所以希望有人可以帮助我。

以下是我的组件结构的大致概念:

<Dashboard>
    <Widget1 dataFetcher=()=>{}>
        <Header>
            <Title> ... </Title>
            <Menu>
                <MenuItem {..cosmeticProps} text="OpenSettings" onClick=handleSettingsOpen>
                <MenuItem {..cosmeticProps} text="Delete" onClick=handleWidgetDelete>
            </Menu>
        </Header>
        <Body>
            <Settings isOpen isValid fields onValidate onAutoComplete.. </Settings>
            { ifError ? ErrorLayout}
            { ifFetching ? FetchingLayout }
            { ifValid ? DataLayout }
        </Body>
    </Widget1>
    ...
</Dashboard>

这是状态结构(事件处理程序显示为完整性,不是因为它们明确是状态的一部分)

Dash: {
    widgets: {
        widget1: {
            menu: {
                isOpen: true,

                handleSettingsOpen: ()=>{}
                handleWidgetDelete: ()=>{}
            }
            settings: {
                isOpen: true,
                isValid: true,
                fields: [...],

                onValidate: ()=>{},
                onAutoComplete:()=>{},
                onSave:()=>{}
            }
            data: {
                isFetching: false,
                isError: false,
                items: [],

                fetch: ()=>{}
                parse: ()=>{}
            }
        }
        ...
    }
}

选项1:

连接仪表板并根据需要将其传递给子项。即,

连接 - dashboard.js

stateToProps ()=> { widgets: state.widgets }
dispatchToProps ()=> { handleSettingsOpen, handleWidgetDelete handleSettingsSave ... } //Dashboard would bind these with moduleid while rendering
  • 亲:其他一切都可以是'哑巴',单一的事实来源
  • Con:关于状态知道太多,道具/派遣的清单只是传递给丑陋的阅读

选项2:

构建“已连接”窗口小部件并在仪表板中使用它。

连接-widget.js

stateToProps ()=> { state.widgets[props.widgetid] }
dispatchToProps ()=> { handleSettingsOpen, handleWidgetDelete handleSettingsSave ... }
  • Pro:Dashboard现在可以是一个愚蠢的容器,无论如何
  • Con:Widget对状态结构了解得太多了?

选项3: 构建单个组件的连接版本并稍后组装

连接-menu.js

stateToProps ()=> { state.widgets[props.widgetid].menu }
dispatchToProps ()=> { handleSettingsOpen, handleWidgetDelete }

连接-settings.js

stateToProps ()=> { state.widgets[props.widgetid].settings }
dispatchToProps ()=> { handleSave, handleValidate }
  • Pro:每个组件都完全符合它关心的状态
  • Con:听取状态的组件太多了?也是谁'组装'它的问题。

选项3.1: 重组状态为:

Dashboard: {
    widgets: { ..}
    menu: {widgetid: {isopen ..}}
    settings: {widgetid: {widgetid ..}}
}

(国家对这种方法更为奉承,但不确定它是否重要)

总的来说,这可能是幼稚/显而易见的,但对我来说,权衡似乎是有一个父母要么对状态了解得太多,要么太多关于如何将孩子放在一起。你会怎么做到这一点?

1 个答案:

答案 0 :(得分:0)

选项3:菜单和设置是否有必要知道“widgetId”?如果他们只是分别收到属性菜单或设置,它们似乎更可重用。

选项1:是否要为支持的每个窗口小部件更新Dashboard stateToProps和dispatchToProps?

由于这些原因,我喜欢选项2,连接的Widget1。

对于状态嵌套深度,Redux Async Actions有一个“关于嵌套实体的注释”,建议避免深层嵌套实体以避免重复数据。

在您的示例中,如果任何窗口小部件具有重复的菜单或设置状态对象,则规范化状态将允许窗口小部件共享相同的状态。

Dashboard: {
    widgets: {
        widget1: {menuId:1, settingsId: 1, ...},
        widget2: {menuId:1, settingsId: 1, ...},
    },
    menus: {1: {...}},
    settings: {1: {...}}
}

实际上,使用这种结构,菜单和设置只需要知道menuId或settingsId,而不是widgetId。我仍然喜欢连接小部件。