我正在使用react apollo提供的 graphql
HOC获取数据列表 . 例如 . :
const fetchList = graphql(
dataListQuery, {
options: ({ listId }) => ({
variables: {
listId,
},
}),
props: ({ data: { loading, dataList } }) => {
return {
loading,
list: dataList,
};
}
}
);
我在受控的单选按钮组中显示列表,我需要默认选择其中一个项目 . 所选项目的 id
保留在Redux存储中 .
那么,问题是如何在查询成功返回后更新Redux存储(即设置 selectedItem
)?
我想到了一些选择:
选项1
我应该在我的Redux减速机中监听 APOLLO_QUERY_RESULT
动作吗?但这有点尴尬,因为如果查询之前已经运行过,我需要同时收听 APOLLO_QUERY_RESULT
和 APOLLO_QUERY_RESULT_CLIENT
. 并且 operationName
prop仅出现在 APOLLO_QUERY_RESULT
动作中而不是 APOLLO_QUERY_RESULT_CLIENT
动作中 . 因此,我需要剖析每一个 APOLLO_QUERY_RESULT_CLIENT
动作,以了解它的来源 . 是否有一种简单直接的方法来识别查询结果操作?
选项2
我应该在 componentWillReceiveProps
中发送单独的操作,如 SELECT_LIST_ITEM
,例如(使用recompose):
const enhance = compose(
connect(
function mapStateToProps(state) {
return {
selectedItem: getSelectedItem(state),
};
}, {
selectItem, // action creator
}
),
graphql(
dataListQuery, {
options: ({ listId }) => ({
variables: {
listId,
},
}),
props: ({ data: { loading, dataList } }) => ({
loading,
items: dataList,
}),
}
),
lifecycle({
componentWillReceiveProps(nextProps) {
const {
loading,
items,
selectedItem,
selectItem,
} = nextProps;
if (!selectedItem && !loading && items && items.length) {
selectItem(items[items.length - 1].id);
}
}
})
);
选项3
我应该直接使用 withApollo
来使用Apollo客户端,然后使用 client.query(...).then(result => { /* some logic */ selectItem(...)})
调度我的操作 . 但是,我会放弃react-apollo集成的所有好处,所以不是一个真正的选择 .
选项4
在查询返回后,我是否应该根本不更新Redux存储?因为我也可以实现一个选择器,如果它被设置则返回 selectedItem
如果没有,它会尝试通过浏览商店的 apollo
部分来派生它 .
我的选择都不能让我满意 . 那么,我该怎么做呢?
6 回答
我会做类似于 Option 2 的事情,但将生命周期方法放入实际的Component中 . 这样,生命周期中的业务逻辑将与从Container继承的props分离 .
所以像这样:
应该有足够的'道具',如:
我会听取componentDidUpdate中的更改,当它们发生调度时,会在Redux商店中设置selectedItem
我使用了一个稍微好一点的选项2版本 . 我在撰写结束时使用withLoader Hoc .
WithLoader hoc渲染组件基于两个Props isData和isLoading . 如果isData为true,则呈现Wrapped Component,否则呈现加载器 .
我在Component的componentWillMount方法中设置了dataList的第一项 . 组件不会挂载,直到我们得到dataList,这是由withLoader hoc确保的 .
在我看来,最好的方法是创建 hoc 的 Option 2 的稍微修改和可组合的版本,它将与
graphql
hoc类似地使用 . 以下是我想到的一个示例用法:最简单的实现将是这样的:
即使我没有尝试过这个伪代码,它也没有测试,甚至没有完成,它背后的想法非常简单易懂 . 希望它能帮助别人
我在过去遇到了类似的问题并选择了类似于选项2的东西 . 如果你有自己的redux商店和apollo自己的内部商店,那么在它们之间同步状态就成了问题 .
如果你使用阿波罗,我建议你摆脱你自己的redux商店 . 如果您同时依赖gql服务器和一些其他服务器,请在逻辑上和物理上分离数据 .
一旦你决定使用apollo作为你的'数据源',调度只是变异,获取状态只是查询 . 您还可以使用查询进行筛选,排序等