突变后apollo客户端3缓存不更新

时间:2020-10-04 22:02:50

标签: reactjs apollo-client

首先,如果这是重复的话,我想道歉,但是类似问题中的现有答案都没有帮助我。

我正在使用nextjs 9.5.3和apollo客户端3.2.2。我有一个表单,用户可以填写该表单以更新其个人资料详细信息。提交后,保存的数据将保存在数据库中,并将响应返回给客户端。问题是响应无法更新缓存,但是根据apollo devtools可以在ROOT_MUTATION内找到它。

我使用查询来首先加载用户的数据,然后在突变期间使用结果更新缓存。下面是本地查询和变异。

// fragments


export const editUserProfileFragment= gql`
  fragment EditUserProfileFields on ProfileInterface {
    id
    type
    slug
    name
    location {
      name
      address
      country
      latitude
      longitude
    }
    settings
    createdAt
    isActive
  }
`;

// query
export const editUserProfileQuery = gql`
  query EditUserProfile($slug: String) {
    Profile(slug: $slug) {
      ...EditUserProfileFields
    }
  }
  ${editUserProfileFragment}
`;

// mutation
export const editUserProfileMutation = gql`
  mutation EditUserProfile($id: ObjectID!, $profile: ProfileInput!) {
    editProfile(id: $id, profile: $profile) {
      ...EditUserProfileFields
    }
  }

  ${editUserProfileFragment}
`;

这是我使用查询和变异的方式:

// the query
const { error, data, loading } = useQuery(editUserProfileQuery, {
    variables: { slug },
    fetchPolicy: "network-only",
  })
// data returns a `Profile` object

// the mutation
  const [editUserProfileMutate] = useMutation(editUserProfileMutation)
...
// save data
try {
      const response = await editUserProfileMutate({
        variables: { id, profile: inputdata },
        // update: (cache, { data }) => {
        //   const cachedData: any = cache.readQuery({
        //     query: editUserProfileQuery,
        //     variables: { slug: newProfile.slug }
        //   });
        //   const cacheId = cache.identify(data.editProfile) // to see the id, i wanted to try cache.modify() but didn't how to proceed.

        //   console.log('update.cachedData', cachedData);
        //   console.log('update.cachedData.Profile', cachedData.Profile);
        //   console.log('update.data', data);

        //   const newData = { ...cachedData.Profile, ...data.editProfile }; // i first used [] but 

        //   console.log('newData', newData);


        //   // cache.writeQuery({
        //   //   query: editUserProfileQuery,
        //   //   variables: { slug: newProfile.slug },
        //   //   data: { editProfile: newData }
        //   // })

        //   // cache.modify({
        //   //   id: cacheId,

        //   // })
        // },
        // tried the below but didn't work

        // refetchQueries: [{
        //  query: editProfilePageQuery,
        //  variables: { slug: newProfile.slug },
        // }],
        // awaitRefetchQueries: true
      });

      const updatedProfile = response.data.editProfile;
      console.log('updatedProfile', updatedProfile);

      ....
    } catch (error) {
      ....

    } // trycatch

下面的阿波罗客户主要基于nextjs with-apollo example

...
let apolloClient;

...

  const cache = new InMemoryCache({
    // https://www.apollographql.com/docs/react/data/fragments/#using-fragments-with-unions-and-interfaces
    dataIdFromObject: result => `${result.__typename}:${result._id || result.id || result.name || result.slug || Math.floor(Math.random() * 1000000)}`,
    possibleTypes: {
      ProfileInterface: ["Star", "User"],
    },
    // @see https://www.apollographql.com/docs/react/caching/cache-field-behavior/#merging-non-normalized-objects from console warnings
    typePolicies: 
      User: {
        fields: {
          location: {
            merge(_existing, incoming) {
              return incoming;
            },
          },
        },
      },
    },
  });


function createClient() {
  const link = makeLink();
  
  return new ApolloClient({
    cache,
    link,
    connectToDevTools:typeof window !== 'undefined',
    ssrMode: typeof window === 'undefined',
  });
}

export function initializeApollo(initialState = null) {
  const _apolloClient = apolloClient ?? createClient()

  if (initialState) {
    const existingCache = _apolloClient.extract()
    console.log('existingCache', existingCache);
    // _apolloClient.cache.restore({ ...existingCache, ...initialState }) // commented out on purpose
    _apolloClient.cache.restore(initialState)
  }

  if (typeof window === 'undefined') return _apolloClient
  if (!apolloClient) apolloClient = _apolloClient

  return _apolloClient
}

export function useApollo(initialState) {
  const store = useMemo(() => initializeApollo({ initialState }), [initialState])
  return store
}

1 个答案:

答案 0 :(得分:0)

因此,在浏览了后端源代码之后,我发现我不是从数据库中返回更新的值,而是从旧值中返回。我修复了它,它按预期工作。