I'm fetching a list of data with the graphql HOC provided by react apollo. E.g.:
const fetchList = graphql(
dataListQuery, {
options: ({ listId }) => ({
variables: {
listId,
},
}),
props: ({ data: { loading, dataList } }) => {
return {
loading,
list: dataList,
};
}
}
);
I'm displaying the list in a controlled radio button group and I need to select one of the items by default. The id of the selected item is kept in the Redux store.
So, the question is how to update the Redux store (i.e. set the selectedItem) after the query successfully returns?
Some options that came to my mind:
Option 1
Should I listen for APOLLO_QUERY_RESULT actions in my Redux reducer? But that is kind of awkward because then I would need to listen to both APOLLO_QUERY_RESULT and APOLLO_QUERY_RESULT_CLIENT if the query already ran before. And also the operationName prop is only present in the APOLLO_QUERY_RESULT action and not in APOLLO_QUERY_RESULT_CLIENT action. So i would need to dissect every APOLLO_QUERY_RESULT_CLIENT action to know where that came from. Isn't there an easy and straight forward way to identify query result actions?
Option 2
Should I dispatch a separate action like SELECT_LIST_ITEM in componentWillReceiveProps e.g (using 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);
}
}
})
);
Option 3
Should I make use of the Apollo client directly by injecting it with withApollo and then dispatch my action with client.query(...).then(result => { /* some logic */ selectItem(...)}). But then I would loose all the benefits of the react-apollo integration, so not really an option.
Option 4
Should I not update the Redux store at all after the query returns? Because I could also just implement a selector that returns the selectedItem if it is set and if not it tries to derive it by browsing through the apollo part of the store.
None of my options satisfy me. So, how would I do that right?