【问题标题】:Structuring state for a react/redux appreact/redux 应用程序的结构状态
【发布时间】:2016-03-04 20:21:15
【问题描述】:

我正在努力构建 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:

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

Connected-dashboard.js

stateToProps ()=> { widgets: state.widgets }
dispatchToProps ()=> { handleSettingsOpen, handleWidgetDelete handleSettingsSave ... } //Dashboard would bind these with moduleid while rendering
  • 专业人士:其他一切都可能是“愚蠢的”,唯一的事实来源
  • 缺点:对状态了解太多,只是传递下去所需的道具/调度列表会让人难以阅读

选项 2:

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

connected-widget.js

stateToProps ()=> { state.widgets[props.widgetid] }
dispatchToProps ()=> { handleSettingsOpen, handleWidgetDelete handleSettingsSave ... }
  • 专业人士:仪表板现在可以是一个哑容器,无论如何都是这样
  • 缺点:Widget 对状态结构了解太多?

选项 3: 构建各个组件的连接版本并在以后组装

connected-menu.js

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

connected-settings.js

stateToProps ()=> { state.widgets[props.widgetid].settings }
dispatchToProps ()=> { handleSave, handleValidate }
  • Pro:每个组件都获得了它所关心的状态片段
  • Con:监听状态的组件太多?还有谁“组装”它的问题。

选项 3.1: 将状态重组为:

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

(State 对这种方法比较平坦,但不确定它是否重要)

总体而言,这可能是幼稚/显而易见的,但对我来说,权衡似乎是让父母对国家了解太多,或者对孩子的组合方式了解太多。您将如何处理?

【问题讨论】:

  • re: option3,组件不监听状态,store可以自己push更新,不用担心订阅太多
  • 我同意选项 3 是最好的。还要始终尝试使您的数据结构尽可能平坦。这太嵌套了Dash: { widgets: { widget1: { menu: {
  • 感谢您的回复-您能解释一下为什么嵌套结构不好吗?如果稍后我需要删除一个小部件,我可以将它从小部件结构中删除;如果它是平的,我需要从其他所有顶级项目中清理它;这会带来什么好处?

标签: javascript reactjs redux react-redux


【解决方案1】:

选项 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: {...}}
}

其实,有了这个结构,Menu 和 Settings 只需要知道 menuId 或者 settingsId,而不需要 widgetId。不过我还是更喜欢连接小部件。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-05-20
    • 2019-03-09
    • 2016-06-11
    • 1970-01-01
    • 1970-01-01
    • 2020-12-26
    • 1970-01-01
    相关资源
    最近更新 更多