2

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

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

Connected-dashboard.js

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

选项 2:

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

连接的widget.js

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

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

连接菜单.js

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

连接的settings.js

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

选项 3.1:将状态重组为:

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

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

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

4

1 回答 1

0

Option 3: Does it make sense for Menu and Settings to know "widgetId"? It seems they would be more reusable if they simply receive the properties menu or settings respectively.

Option 1: Do you want to update Dashboard stateToProps and dispatchToProps for each widget component supported?

For these reasons, I like option 2, the connected Widget1.

As for state nesting depth, Redux Async Actions has a "Note on Nested Entities" that suggests avoiding deeply nested entities to avoid duplicate data.

In your example, if any widgets had duplicate menu or settings state object, a normalized state would allow the widgets to share the same state.

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

Actually, with this structure, Menu and Settings only need to know menuId or settingsId, not widgetId. I still prefer connecting the widget though.

于 2016-04-06T16:26:35.143 回答