With the two following schema:
type Cart {
id:ID!
...
createdAt:DateTime
updatedAt:DateTime
items:[CartItem!]
}
type CartItem {
id:ID!
cartId:ID!
name:String!
price:Float
}
type Query {
userCart(id:ID!):Cart
cartItem(id:ID!):CartItem
}
and the following queries:
const CART_QUERY = gql`query GetCart {
userCart {
id
createdAt
updatedAt
items {
id
name
price
}
}
}`;
const CART_ITEM_QUERY = gql`query CartItem($id:ID!) {
cartItem(id:$id) {
id
name
price
}
}`;
If one component is defined as
function CartComponent() {
const { loading, error, data } = useQuery(CART_QUERY);
return ( /* content here */ );
};
which populates the cache with, for example:
Cart:123
CartItem:5463
CartItem:5472
and another component, child of CartComponent
, is defined as
function CartItemEditComponent({ itemId }) {
const [ fetch, { loading, error, data } ] = useLazyQuery(CART_ITEM_QUERY);
useEffect(() => {
// itemId = 5463
fetch({ id:itemId }, { fetchPolicy:'cache-only' });
}, [itemId, fetch]);
console.log( data, error ); // <--- always : undefined undefined
return ( /* content here */ );
};
If I remove the option fetchPolicy:'cache-only'
then a server request is made and data
does contain the CartItem
; no change to the cache , However, with the cache-only
fetch policy, the component is still rendered, but data
is empty with no error.
Why is data
inside CartItemEditComponent
empty with fetchPolicy:'cache-only'
?
If the query is the issue, then what should be the value of CART_ITEM_QUERY
?
The way I make it work, right now, is by doing this:
function CartComponent() {
const { loading, error, data, client } = useQuery(CART_QUERY);
useEffect(() => {
const items = data?.userCart?.items ?? [];
for (const item of items) {
client.writeQuery({
query: CART_ITEM_QUERY,
data: { cartItem: item },
variables: { id: item.id }
});
}
}, [data, client]);
return ( /* content here */ );
};
The cache isn't modified, but the CartItemEditComponent
suddenly has a result.
Based on my comment above something like this should work:
function CartItemEditComponent({ itemId }) {
const [ fetch, { loading, error, data } ] = useLazyQuery(CART_ITEM_QUERY);
useEffect(() => {
// itemId = 5463
fetch({ id:itemId }, { fetchPolicy:'cache-only' });
}, [itemId, fetch]);
if (error) {
console.log( error );
}
if (!data && loading) {
<p>loading</p>
}
if (!loading && data) {
return ( /* content here */ );
}
};
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.