如何在执行多个Apollo查询和突变后更新本地状态?

问题描述 投票:0回答:1

我是Apollo的新手,我缺少了一些东西。我有一个获取当前登录用户的查询,我在页面加载时运行它,它从我的一个顶级组件中执行(同样的一个组件也包含react-router的匹配逻辑)。

export const GET_USER = gql`
  query {
    me {
      id
      email
    }
  }
`

然后在DOM树中嵌套了登录和注销按钮,这两个按钮都会触发突变,从而设置或取消当前用户的会话。 但是... 我如何更新应用顶部的状态?

我读过 本博文 建议将Apollo Hooks包装到其他自定义钩子中。

const useAuth = () => {
  const { data: getUserData } = useQuery(GET_USER)
  const [login, { data: loginData } = useMutation(LOGIN)
  const [logout, { data: logoutData } = useMutation(LOGOUT)

  // Should I find out here if I have a user id or not?
  // It's doable, but not clean

  return { login, logout, userId }
}

对我来说,用这种方式提出请求是很不直观的 我很容易理解在Redux或MobX动作中产生这些副作用... 因此,我将直接使用Apollo客户端,即使这不是Apollo文档中建议的解决方案。

我有什么地方做得不对?

reactjs graphql react-apollo apollo-client
1个回答
1
投票

它将看起来像下面的东西。重要的部分是,一旦收到响应,突变就会调用更新函数。这就是你手动更新缓存的位置。目标是替换apollo缓存中的 "me "的值。令人满意的部分是,一旦你把这个工作做好了,从useQuery中检索到的数据就会自动更新(因此使用这个钩子重新渲染组件)。下面是这个钩子的链接 文件.

const useAuth = () => {
  const { data: getUserData } = useQuery(GET_USER)
  const [mutateLogin] = useMutation(LOGIN)
  const [mutateLogout] = useMutation(LOGOUT)

  function login(..args) {
    mutateLogin({
      variables: args,
      update(proxy, {data}) {
        proxy.writeQuery({
          query: GET_USER,
          data: {
            me: (GET USER FROM data)
          }
        })
      }
    })
  }

  function logout() {
     mutateLogout({
       update(proxy, {data}) {
         proxy.writeQuery({
           query: GET_USER,
           data: {
             me: null
           }
         });
       }
     })
  }

  return { login, logout, userId }
}

0
投票

在我的应用程序中,我使用 apollo-cache-inmemory 来管理app的状态。我的app是一个单源的真理状态,好像是重头戏。当你想在Apollo状态下操作数据时,你应该使用 useQuery 来查询客户的数据,使用 useMutation 来更新Apollo状态。你可以在Apollo中阅读更多关于如何与缓存数据交互的信息。此处. 这是一个例子。 在... client.js:

import { InMemoryCache } from 'apollo-cache-inmemory';
import { HttpLink } from 'apollo-link-http';
import { ApolloClient } from 'apollo-client';

const client = new ApolloClient({
  link: new HttpLink(),
  cache: new InMemoryCache(),
  resolvers: {
    Mutation: {
      setSearchText : (_, { searchValue }, {cache}) => {
        cache.writeData({
          data: {
            searchText: searchValue,
          },
	    })
      }
    }
  }
});

const initialState = {
  searchText: ''
}

cache.writeData({ data: initialState})

SearchBox.js

import React from 'react'
import { useQuery, useMutation } from '@apollo/react-hooks'
import gql from 'graphql-tag'

const SET_SEARCH_TEXT = gql`
	mutation SetSearchText($searchValue: String!) {
		setSearchText(searchValue: $searchValue) @client
	}
`

const GET_SEARCH_TEXT = gql`
	query SearchText {
		searchText @client
	}
`

const SearchBox = () => {
  const { data: searchTextData, loading, error } = useQuery(GET_SEARCH_TEXT)
  const [setSearchText] = useMutation(SET_SEARCH_TEXT)
  const [value, setValue] = React.useState(searchTextData.searchText || '')
  
  handleChange = (e) => {
    setValue(e.target.value)
  }
  
  onSubmit = () => {
    setSearchText({variables: { searchValue: value }}).then(data => console.log(data))
  }
  return (
    <div>
      <input type="text" value={value} onChange={handleChange} />
      <button onClick={onSubmit}>Submit</button>
    </div>
  )
}
© www.soinside.com 2019 - 2024. All rights reserved.