阵营阿波罗和终极版:将自定义减速与阿波罗状态
当使用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]
我的解决办法是使用recompose到compose
商店和阿波罗通过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);
这也让我们检查使用branch的graphql
负荷状态,所以我们不跑selectProps
,直到数据可用。
感谢Daniel Rearden's answer指引我在正确的方向。
你是对的 - 由减速器组成,每个减速器不应该有权访问其余的州。问题是为什么你甚至需要你的商店包含apollo.item.list[ui.selectedItem]
单独的值。
大概你需要这个值来渲染你的容器中正确的东西。为了计算它,你只需要一个合适的选择器在mapStateToProps内调用。通过整个状态,获得你需要的价值。一个简单的例子:
const mapStateToProps = state => ({
itemToShow: itemSelector(state)
})
const itemSelector = ({ apollo, ui }) => apollo.item.list[ui.selectedItem]
你需要来包装容器中都connect
和graphql
肝卵圆细胞,使这项工作,但据我所知,无论你把它包在一个或另一个没有按第一这似乎不重要。您还可以使用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
更清洁的方式。
不是你的问题的真正答案,但我发现ReactQL是一个伟大的入门工具包,为你照顾所有这些东西。它具有Apollo + React + Redux的所有样板,包括自定义的Redux缩减器。看看他们是如何做到的。
谢谢,这是有用的输入。我喜欢第一个解决方案,因为memoization选项和可重复使用的选择器(我可能需要这个在多个容器中 - 因此希望将它存储在第一位)。但正如你所说,这不是真正的使用阿波罗的可靠方法。第二种选择似乎将大量工作放到了'graphql'专题讨论区,似乎不能跨容器重用? – duncanhall
此外,第二个选项似乎只在数据更改时才起作用。如果之后selectedItem状态发生改变,那么'itemToShow'值不会被更新? – duncanhall