-
Notifications
You must be signed in to change notification settings - Fork 2.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Local state resolvers with reactive data #5550
Comments
The If you want to update the I too also didn't understand this, and struggled for days reading the documentation and just trying it out until I found the issue. Edit: you can use |
@freshollie Can give an example of writing a new version of the query into the cache? Also, it seems like |
@dcecile Please see: https://codesandbox.io/s/apollo-local-state-management-zrwel The The reason the |
@freshollie OK I understand now, thanks 🙏 I'd be nice if Apollo treated My feature request is if the source of This way I wouldn't need to do all of the bookkeeping and updating myself (i.e. which React components are active, which fragments they use, which local resolvers of those fragments are used, and how to recalculate the results of all those local resolvers). |
Thanks for your help @freshollie!
That would be really nice! And that would finally make Apollo the perfect fit for our local state management! |
FYI, @sirctseb posted to StackOverflow with an alternate workaround, to use a top-level client.watchQuery({ query: sourceQuery }).subscribe(value =>
client.writeData({ data: { resolvedDevice: doStuffWithTheData(value.data.selectedDevice) } }); (He explains that this solution needs extra bookkeeping, potentially automated using a HOC, to make sure that the |
In Apollo Client 3.0, a better way to implement this behavior is to us a custom import { InMemoryCache } from "@apollo/client";
const LocalStateValueQuery = gql`
query StateQuery {
localState {
value
}
}
`;
const cache = new InMemoryCache({
typePolicies: {
Greeting: {
fields: {
name(existingName: string) {
return existingName || cache.readQuery({
query: LocalStateValueQuery,
})?.localState?.value;
},
},
},
},
}); Because the |
If you want to get a little fancier, you could give your const cache = new InMemoryCache({
typePolicies: {
LocalState: {
// Indicate that the ID of the singleton LocalState object does not depend
// on any of its fields, and is therefore constant: "LocalState:{}".
keyFields: [],
},
Greeting: {
fields: {
name(existingName: string, { readField, toReference }) {
return existingName || readField("value", toReference({
__typename: "LocalState",
}));
},
},
},
},
}); This pattern is also fully reactive, and should be much faster because it skips the overhead of |
While I stand by my recommendations above, I'm not entirely happy with either one. Here's the API I would really like to use: const cache = new InMemoryCache({
typePolicies: {
Greeting: {
name() {
return nameVar.get();
}
}
}
});
// A default value can be provided when the variable is created,
// which also allows TypeScript to enforce the type.
const nameVar = cache.variable("John");
// The variable can be updated anywhere, like so:
nameVar.set("Ben"); |
Ok, here's my take on the reactive local variable idea: #5799 |
#5799 was merged, so I'll close this off. Thanks! |
Nice! Thanks @benjamn for your work, can't wait to try it! |
Hi 👋
I'm playing around with Apollo's Local State Management feature and I found a strange behaviour that has not been made clear in the documentation. Could you help me understand if this is a bug, or if it's by design and if there's a workaround?
Here it is:
With this setup, everything is ok on the first query with
react-apollo
hook:But when I update the local state with:
The previous query is correctly re-run, but the local field
name
has not been updated:You can find a Sandbox set up here: https://codesandbox.io/s/apollo-local-state-management-5dy2f?fontsize=14&module=%2Fsrc%2FApolloProvider.tsx
Is it intended? Do you plan on supporting this kind of feature?
Thank you for your help!
The text was updated successfully, but these errors were encountered: