Apollo-client:cacheRedirect与dataIdFromObject的适用场景及缓存疑问
Great question—let’s break down exactly when to use each of these Apollo caching tools, then walk through your specific scenario to clear things up.
1. When to use dataIdFromObject
dataIdFromObject is your cache's foundational setup—it defines how Apollo uniquely identifies every object in its normalized cache. Think of it like assigning a primary key to each type of data you store.
- Use this whenever your entities have a consistent unique identifier (like your books'
uuid) that’s shared across all queries for that entity. - It ensures Apollo stores the same object only once, even if fetched via different queries. For example, a book fetched in your list view and the same book fetched in a detail view will be recognized as the same object because they share the same data ID.
- Key scenario: Any time you want to eliminate duplicate copies of the same entity in the cache, no matter how you query for it.
Here’s a typical implementation for your book example:
dataIdFromObject: (object) => { switch (object.__typename) { case 'Book': return `Book:${object.uuid}`; default: return defaultDataIdFromObject(object); } }
2. When to use cacheRedirects
cacheRedirects is a targeted lookup tool—it tells Apollo how to find existing cached data when a new query runs, instead of hitting the network. It’s a "bridge" for when Apollo can’t automatically match a query to cached data using normalized IDs alone.
- Use this when your query uses a different shape, parameter name, or identifier than what’s already stored in the cache.
- For example: If your detail query uses a
bookIdparameter that doesn’t directly map to thedataIdof your Book objects, or if you’re querying a single item but the cache only has a list (thoughdataIdFromObjectusually handles this if identifiers are consistent). - Key scenario: When you need to override Apollo’s default cache matching logic to connect a new query to existing cached data.
Your Specific Scenario: List View to Detail View
You’re using dataIdFromObject with your books’ uuid—let’s assume your detail query looks like this:
query DetailView($uuid: String!) { book(uuid: $uuid) { uuid title abstract # other fields } }
Do you need cacheRedirects here?
No, you don’t! Here’s why:
- When your list query runs, Apollo stores each Book in the cache with an ID like
Book:[uuid](thanks to yourdataIdFromObjectsetup). - When you run the detail query for a specific
uuid, Apollo recognizes it’s looking for a Book entity with thatuuid. It directly looks up the cached object with IDBook:[uuid]. - As long as all fields requested in the detail query are already present in the cached Book object, Apollo will return the cached data instead of making a network request.
When would you need cacheRedirects for this flow?
Only if your detail query used a non-matching identifier. For example, if your detail query used an id parameter instead of uuid, but your Book objects only have uuid as their unique key. Then you’d add a redirect rule like:
cacheRedirects: { Query: { book: (_, args, { getCacheKey }) => getCacheKey({ __typename: 'Book', uuid: args.id }), }, }
This tells Apollo: "When someone queries a book by id, use that id as the uuid to look up the cached Book object."
内容的提问来源于stack exchange,提问作者tgk

