2015-11-04 86 views
0

我已經使用Redux幾個星期了,我對它很滿意,而且我已經習慣了Redux方式。我正在使用它與React。由於這兩件事對我來說都是新的,所以還有很多東西要學。通過道具向下傳遞動作

我有一個問題 - 也許我做錯了什麼?讓我告訴你:

我有一個組件結構,看起來像這樣:

App //root of the application aka smart component 
    CampaignTable 
    CampaignHeaderRow 
     CampaignHeader 
    CampaignDataRow 
     CampaignData 

應用程序組件被初始化作爲(僅相關代碼):

import * as DashboardActions from '../actions.js' 

function select(state){ 
    return { 
    campaigns: state.campaigns, // array of campaign objects, has name, id, time created etc 
    order: state.order // sort format "byWhichField" 
         // will affect the way how campaigns are displayed 
    } 
} 

function mapDispatchToProps(dispatch){ 
    return bindActionCreators(DashboardActions, dispatch) 
} 

export default connect(select, mapDispatchToProps)(App); 

應用程序現在可以訪問狀態和所有動作作爲道具。

我現在用它看到的問題是:

我想CampaignHeader火,這將改變state.order狀態的動作。假設我會在內部製作<th>Text</th> CampaignHeader clickable。這將觸發此行爲,以更改state.order這將影響下一次移交時的廣告訂單。

所以我有我的動作App道具。將它傳遞到 CampaignHeader我會:

  • 傳下來CampaignHeader道具
  • 將其分配到變量中CampaignHeader並傳遞下來的道具CampaignHeaderRow
  • 將其分配給CampaignHeaderRow中的變量並將其作爲道具傳遞給CampaignHeader
  • 將其分配到變量中CampaignHeader,並觸發onClick事件中的作用....

這是很多樣板,作業和包傳球!只是爲了開始行動。

沿途的所有組件都知道此操作。

當我決定實現此功能時,我打開了CampaignHeader組件文件。我添加了邏輯並調用了動作,我已將動作添加到動作文件中。我需要的只是獲得一套道具。 CampaignHeader組件不包含對其父項的引用,所以我不知道該道具從哪裏注入(在這個例子中顯而易見,但我希望你能得到一個觀點)。

如果我的組件結構更深,該怎麼辦?

該方法是否正確?

我可以解決這個問題嗎?

UPDATE:

由於@Errorpro建議會是OK連接單動state.orderCampaignHeader

擔心:如果我會做到這一點,我會一直這樣做。

回答

1

Redux github回購的問題部分討論瞭如何使用多個連接,或者如果應該從頂部通過道具傳遞所有內容,並且Dan Abramov(Redux的創建者說:

[...]

沒有人主張單一的連接。

[...]

「單」 僅指之類的小應用程序我們在 示例中創建了一個。請隨意修改文檔以更好地闡明這一點。我 現在忙於其他項目,所以請不要期待這個問題到 得到任何動作,除非有人做PR。你也可以這樣做。

的評論可能確保在上下文中,但這樣檢查出整個問題線程https://github.com/rackt/redux/issues/419#issuecomment-140782462

1

如果你使用REDX,你應該知道愚蠢和聰明的組件。所以我們使用這個結構:

component 
    index.js 
    Component.js 
    ComponentContainer.js 

愚蠢的組件只是獲取道具並呈現它。智能組件更有趣。那就是:

export default compose(
    relay({ 
    fragments: { 
     viewer:() => Relay.QL` 
     fragment on Viewer { 
      any data from relay 
     } 
     `, 
    }, 
    }), 
    connect(
    null, 
    { 
     onCreate: createUserAction, 
    }, 
    (stateProps, actionProps, parentProps) => ({ 
     ...parentProps, 
     onCreate={() => actionProps.onCreate('user')}, 
    }) 
), 
)(Component); 

所以,parentProps和功能的onCreate將是愚蠢的組件的道具。在那裏你可以使用this.props.onCreate並調用它或者將它傳遞給更遠的地方。

+0

但路過的父親是我的問題,我必須做4次在我的簡單的例子。我知道流程工作如何以這種方式發現它很奇怪 – Kocur4d

+0

在react.js中,只有一種正確的方法可以將它進一步傳遞 - 道具。如果你使用redux連接你的方式沒問題。如果你需要在最終的失敗中獲得這個動作,你可以在那裏使用智能組件,並在那裏調用你的動作。在你的情況下,將很好創建CampaignHeaderContainer,並在那裏連接調度和操作。正如我的例子。 – Errorpro

+0

所以你建議添加另一個連接到** CampaignHeaderRow **? – Kocur4d

1

傳遞動作 - 像任何其他道具一樣 - 從父母到孩子,孫輩等都是慣用的React方式。在我看來,你的方法是正確的;即使感覺不對。

但有幾種選擇。

React中有一項稱爲上下文的功能。上下文允許將字段從高階組件傳遞到低階組件,同時跳過中間人。但是,這是一個實驗性功能,所以我現在建議避免它。 https://facebook.github.io/react/docs/context.html

此外,還有一個Redux特定的方式,您可以使您選擇的任何低階節點成爲「智能組件」(在Redux意義上)。也就是說,您可以將您的類導出包裝在連接函數中,以便直接將其插入到存儲中,方法與您爲根節點完全相同。

我個人傾向於堅持自上而下的方式。可能會涉及一些樣板,但至少這意味着您的應用程序很容易推理。

+0

所以你不會試圖將商店的**單個動作**和一個非常特殊的部分**連接到** CampaignHeader **,作爲@Errorpro的建議? – Kocur4d

+0

我的方法通常是最大限度地減少我的智能組件。即單個智能根組件。或者,在使用react-router時,有幾個智能路由處理程序。但是,做任何你覺得有意義的事情。 –

+0

這是一個JavaScript,所以它是一個狂野的狂野西部......你可以做任何你喜歡的事情; P我可以讓我的店鋪成爲全球性的,展現給全世界。我更感興趣的是就社區如何解決這個問題獲得一般意見。謝謝你,小夥伴!:) – Kocur4d