如何在react-apollo中刷新变量?附用户登录查询场景
Great question! Let’s walk through practical, actionable solutions that fit your specific user journey—where you need to refresh query variables (like the user ID stored in localStorage) after login or when user data changes.
1. Use useQuery's refetch Method for Manual Refresh
When your user lands on the profile page post-login, you can explicitly trigger a refetch of the query with the latest userId from localStorage. This works perfectly for cases where you know the variable has updated (like right after a login redirect).
Example Code:
import { useQuery, gql } from '@apollo/client'; const GET_USER_PROFILE = gql` query GetUserProfile($userId: ID!) { user(id: $userId) { id firstName lastName email # Add other user fields you need } } `; function UserProfile() { // Grab the latest userId from localStorage const userId = localStorage.getItem('userId'); const { loading, error, data, refetch } = useQuery(GET_USER_PROFILE, { variables: { userId }, // Skip the query if userId isn't available (e.g., before login) skip: !userId, }); // Trigger refresh manually (e.g., after user updates their info) const handleRefreshProfile = () => { refetch({ userId: localStorage.getItem('userId') }); }; if (loading) return <p>Loading profile...</p>; if (error) return <p>Oops, error loading profile: {error.message}</p>; return ( <div> <h1>{data.user.firstName} {data.user.lastName}</h1> <p>Email: {data.user.email}</p> <button onClick={handleRefreshProfile}>Refresh Profile</button> </div> ); }
2. Listen for localStorage Changes to Auto-Refresh
Since you’re storing the userId in localStorage, set up an effect to listen for changes to this value. When it updates (like after a successful login), the query will automatically re-run with the new variable.
Example Code:
import { useQuery, gql } from '@apollo/client'; import { useEffect, useState } from 'react'; const GET_USER_PROFILE = gql`/* Same query as above */`; function UserProfile() { const [userId, setUserId] = useState(localStorage.getItem('userId')); // Listen for changes to localStorage useEffect(() => { const handleStorageUpdate = (e) => { if (e.key === 'userId') { setUserId(e.newValue); } }; window.addEventListener('storage', handleStorageUpdate); // Clean up the listener when component unmounts return () => window.removeEventListener('storage', handleStorageUpdate); }, []); const { loading, error, data } = useQuery(GET_USER_PROFILE, { variables: { userId }, skip: !userId, }); // ... rest of your profile component }
3. Use useLazyQuery for On-Demand Execution
If you don’t want the query to run immediately (e.g., you need to wait until the userId is confirmed after login), useLazyQuery lets you execute the query manually once you have the correct variable.
Example Code:
import { useLazyQuery, gql } from '@apollo/client'; import { useEffect } from 'react'; const GET_USER_PROFILE = gql`/* Same query as above */`; function UserProfile() { const [getUserProfile, { loading, error, data }] = useLazyQuery(GET_USER_PROFILE); // Run the query when the component mounts (or when userId becomes available) useEffect(() => { const storedUserId = localStorage.getItem('userId'); if (storedUserId) { getUserProfile({ variables: { userId: storedUserId } }); } }, [getUserProfile]); // ... rest of your profile component }
4. Update Apollo Cache Directly After Login (Skip Refetch Altogether)
Instead of relying on refetching later, write the user data from your login mutation directly into Apollo’s cache. When the profile page loads, it will pull the latest data from the cache immediately—no refetch needed.
Example Code (Login Mutation):
import { useMutation, gql, useApolloClient } from '@apollo/client'; const LOGIN = gql` mutation Login($email: String!, $password: String!) { login(email: $email, password: $password) { token user { id firstName lastName } } } `; function LoginPage() { const client = useApolloClient(); const [login, { loading }] = useMutation(LOGIN, { onCompleted: (data) => { // Save data to localStorage localStorage.setItem('token', data.login.token); localStorage.setItem('userId', data.login.user.id); localStorage.setItem('firstName', data.login.user.firstName); localStorage.setItem('lastName', data.login.user.lastName); // Write user data directly to Apollo cache client.writeQuery({ query: gql` query GetUserProfile($userId: ID!) { user(id: $userId) { id firstName lastName } } `, variables: { userId: data.login.user.id }, data: { user: data.login.user }, }); // Redirect to profile page window.location.href = '/profile'; }, }); // ... Login form handling logic here }
内容的提问来源于stack exchange,提问作者Putxe

