2017-07-07 80 views
0

當使用react-apollo與終極版,服務器上的數據在終極版商店下apollo鍵緩存:陣營阿波羅和終極版:將自定義減速與阿波羅狀態

{ 
    apollo: // results from Apollo queries 
} 

創建自己的減速和相應的狀態後,樹,你的店可能是這樣的:

{ 
    apollo: { ... }, 
    ui: { 
     selectedItem: 2; 
     showItems: 6 
    } 
} 

試想一下,有哪些改變的ui.selectedItem價值的作用,而這種價值的項目在apollo某處埋藏指數對象。

隨着reducer composition,我們的ui州的減速器將正確無法訪問阿波羅州下的任何東西。

在我們的組件,我們可以通過mapStateToProps訂閱我們ui狀態變化,並且我們可以使用react-apollo GraphQL容器(或@graphql裝飾)阿波羅結果映射到道具。

但是,我們如何用我們的應用程序中的Apollo結果和其他狀態計算出的值更新我們的商店?

例如,如果apollo.item.list是項目的數組,ui.selectedItem是要在該列表中的目標指數 - 如何可以在商店包含一個值:

apollo.item.list[ui.selectedItem] 

回答

2

我的解決辦法是使用recomposecompose商店和阿波羅通過mapProps狀態一起:

import { mapProps, compose } from ‘recompose’; 

const mapStateToProps = state => ({ 
    selectedItem: state.ui.selectedItem 
}) 

const mapDataToProps = { 
    props: ({ data }) => ({ list: data.item.list }) 
} 

const selectProps = mapProps(({ selectedItem, list}) => ({ 
    item: list[selectedItem] 
})) 

export default compose(
    connect(mapStateToProps, {}), 
    graphql(MY_QUERY, mapDataToProps), 
    selectProps 
)(MyComponent); 

這也讓我們檢查使用branchgraphql負荷狀態,所以我們不跑selectProps,直到數據可用。

感謝Daniel Rearden's answer指引我在正確的方向。

3

你是對的 - 由減速器組成,每個減速器不應該有權訪問其餘的州。問題是爲什麼你甚至需要你的商店包含apollo.item.list[ui.selectedItem]單獨的值。

大概你需要這個值來渲染你的容器中正確的東西。爲了計算它,你只需要一個合適的選擇器在mapStateToProps內調用。通過整個狀態,獲得你需要的價值。一個簡單的例子:

const mapStateToProps = state => ({ 
    itemToShow: itemSelector(state) 
}) 

const itemSelector = ({ apollo, ui }) => apollo.item.list[ui.selectedItem] 

你需要來包裝容器中都connectgraphql肝卵圓細胞,使這項工作,但據我所知,無論你把它包在一個或另一個沒有按第一這似乎不重要。您還可以使用reselect進行研究,這對於此類派生數據非常理想。由於Apollo的商店大部分並不是真正用於如上所述的設計,因此您可能會發現將此分解爲兩個步驟更容易:首先,將ui.selectedItem分配給prop mapStateToProps。然後,如果你與graphql HOC包裝容器時,您可以參考該道具,像這樣:

const mapStateToProps = state => ({ selectedItem }); 
const mapDataToProps = ({ ownProps: { selectedItem }, data }) => ({ 
    itemToShow: data.item.list[selectedItem] 
}); 
const ContainerWithData = graphql(myQuery, { props: mapDataToProps })(MyContainer); 

export default connect(mapStateToProps)(ContainerWithData); 

或者你可以使用阿波羅反應的compose更清潔的方式。

+1

謝謝,這是有用的輸入。我喜歡第一個解決方案,因爲memoization選項和可重複使用的選擇器(我可能需要這個在多個容器中 - 因此希望將它存儲在第一位)。但正如你所說,這不是真正的使用阿波羅的可靠方法。第二種選擇似乎將大量工作放到了'graphql'專題討論區,似乎不能跨容器重用? – duncanhall

+0

此外,第二個選項似乎只在數據更改時才起作用。如果之後selectedItem狀態發生改變,那麼'itemToShow'值不會被更新? – duncanhall

-1

不是你的問題的真正答案,但我發現ReactQL是一個偉大的入門工具包,爲你照顧所有這些東西。它具有Apollo + React + Redux的所有樣板,包括自定義的Redux縮減器。看看他們是如何做到的。