apollo-link-state
apollo-link-state copied to clipboard
Document refetch behavior
I think it would be very helpful to document how refetch
behavior works with apollo-link-state
. I lost a day with what I though was a bug in apollo-link-state
. It didn't occur to me that refetch
would set my state cache back to the defaults I set in withClientState
.
It makes sense after putting all the pieces together. Unfortunately, it took me a day to solve this puzzle 😢
I imagine a lot of people write their queries similar to this:
const queries = gql`
query {
localQuery @client {
someField
}
remoteQuery {
someField
}
}
`;
export default graphql(queries)(MyComponent);
refetch
-ing data
in this scenario will reset localQuery
to whatever is set in withClientState
's defaults
.
Developers will need to find a pattern that allows them to refetch
their remote and local data independently.
Here's a pattern that I'm using. I don't know if it's any good but it's working for me for now.
const httpQueries = gql`
query {
remoteQuery {
someField
}
}
`;
const stateQueries = gql`
query {
localQuery @client {
someField
}
}
`;
export default compose(
graphql(httpQueries, { name: 'httpData' }),
graphql(stateQueries, { name: 'stateData' }),
)(MyComponent);
I agree @anthonator -- I think the whole apollo-link-state defaults
feature is a full of pitfalls. In our app, we're providing/testing our defaults inside of our state-link, and we don't use the Defaults feature at all.
Same issue. It happens to me before when I wrote queries like this:
const queries = gql`
query {
localQuery @client {
someField
}
remoteQuery {
someField
}
}
`
Just like @anthonator mentioned above, refetch
-ing data will reset the localQuery
.
Then I have to separate the localQuery
from the remoteQuery
.
Another issue is that when I mutate some fields of local state, the combined queries above won't get updated. Then again the seprated version works.
I think apollo-link-state is not good at dealing with combination of local and remote queries at the moment, or am I missing something about the goals apollo-link-state aims to acheive?
I too ran into this and think it is unintuitive behavior, at least in how I originally interpreted the docs. It seems like, since fields with the @client
directive resolve to the local cache instead of the network, that refetches to the network therefore should not affect them.
Uups, that explains a few hours of my debugging too. Thanks @anthonator for writing this up!
Is this behavior working as intended?
Facing the same issue. Is there any solution to this problem ?
I specifically have this problem when trying to test a local mutation.
it("should update SearchText when the TextField is changed", async () => {
let apolloClient
const wrapper = mount(
<MockedProvider mocks={mocks} addTypename={false}>
<ApolloConsumer>
{client => {
apolloClient = client
return <Search />
}}
</ApolloConsumer>
</MockedProvider>
)
await wait(0)
wrapper.update()
// make sure search text is empty string on initial query
const { data } = await apolloClient.query({ query: GetSearchRules })
expect(data.searchRules.text).toBe("")
// simulate an on change event on the text field, triggering a local
// state mutation
const event = { target: { value: "new search" } }
const textField = wrapper.find("input")
textField.simulate("change", event)
await wait(0)
wrapper.update()
// check if getSearchText query returns correct string
const { data: newData } = await apolloClient.query({
query: GetSearchRules
})
// fails, because the query needs to be refetched, but cant refetch it
// because it refetching local queries resets it to default state, which is null
expect(newData.searchRules.text).toBe("new search")
})
After I simulate the button click, a local state mutation fires which updates my state. When I make the second query, it fails because the local-state query needs to be refetch, but that causes the local state to be reset.
In my <Search/>
component, if I add refetchQueries={[{ query: GetSearchRules }]}
to the <Mutation/>
component prop, my tests pass, but the UI is broken. If I remove refetchQueries
, tests fail, but UI works as desired.
I've run into it as well