2016-03-04 58 views
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:

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

连接 - 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 ... } 
  • 临:仪表盘现在可以是一个愚蠢的容器,它是无论如何
  • 缺点:小部件知道太多关于国家结构?

选项3: 生成连接各个组件的版本和组装后

连接-menu.js

stateToProps()=> { state.widgets[props.widgetid].menu } 
dispatchToProps()=> { handleSettingsOpen, handleWidgetDelete } 
连接-settings.js

stateToProps()=> { state.widgets[props.widgetid].settings } 
dispatchToProps()=> { handleSave, handleValidate } 
  • 专业版:每个组件都准确地处理它所关注的状态片
  • Con:组件监听状态的组件太多?还有谁是“组装”的问题。

选项3。1: 重组状态为:

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

(州是平坦的这种做法,但不知道这是否重要得多)

总体而言,这可能是幼稚/显而易见的,但对我来说与贸易关闭似乎有一个家长,要么知道太多的国家,要么太多关于儿童如何放在一起。你会如何处理这个问题?

+0

re:option3,组件不听状态,商店可以自己更新_push_,你不用担心订阅过多 – dandavis

+0

我同意选项3是最好的。也总是尽量让你的数据结构尽可能平坦。这太嵌套了'Dash:{widgets:{widget1:{menu:{'。 –

+0

谢谢你的答复 - 你能解释一下_why_嵌套结构是不好的吗?与嵌套,如果以后我需要删除一个小部件,我可以从小部件结构中删除它;如果它是平的,我需要从其他所有顶级项目中清理它;这将提供什么好处? – Naren

回答

0

选项3:菜单和设置知道“widgetId”有意义吗?看起来如果他们只是分别接收属性菜单或设置,他们会更加可重用。

选项1:是否要为每个支持的窗口小部件组件更新控制面板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。尽管如此,我仍然更喜欢连接小部件