首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >执行突变时,ApolloClient所有值均为空。

执行突变时,ApolloClient所有值均为空。
EN

Stack Overflow用户
提问于 2020-07-12 12:43:50
回答 1查看 1.4K关注 0票数 0

我开始使用ApolloClient,我必须说,文档是可怕的。

我的应用程序将使用GraphQL,但是登录需要使用一个简单的POST请求来/login,提供用户名和密码,作为格式数据。

伙计,让它发挥作用完全是一场噩梦。

由于我必须使用apollo-link-rest,所以我必须首先构建我的客户端:

代码语言:javascript
复制
import ApolloClient from 'apollo-client'
import { InMemoryCache } from 'apollo-cache-inmemory'
import { ApolloLink } from 'apollo-link'
import { createHttpLink } from 'apollo-link-http'
import { onError } from 'apollo-link-error'
import { RestLink } from 'apollo-link-rest'

const cache = new InMemoryCache()

const httpLink = new createHttpLink({
  credentials: 'include',
})

const restLink = new RestLink({
  endpoints: {
    localhost: {
      uri: "http://localhost:8080"
    }
  },
  credentials: 'include'
})

const errorLink = onError(({ graphQLErrors, networkError, operation }) => {
  if (graphQLErrors) {
    graphQLErrors.forEach(({ message, locations, path }) => {
      console.log(`[GraphQL error] Message: ${message}, ${path}`)
    })
  }
  if (networkError) {
    console.log(
      `[Network error ${networkError}] Operation: ${operation.operationName}`
    )
  }
})

export const client = new ApolloClient({
  link: ApolloLink.from([errorLink, restLink, httpLink]),
  cache,
})

然后我有一个疑问:

代码语言:javascript
复制
const LOGIN_QUERY = gql`
  mutation doLogin($username: String!, $password: String!, $formSerializer: any) {
    user(input: { username: $username, password: $password})
      @rest(
        path: "/login"
        type: "user"
        method: "POST"
        endpoint: "localhost"
        bodySerializer: $formSerializer
      ) {
        id
        name
      }
  }`

const formSerializer = (data, headers) => {
  const formData = new URLSearchParams()
  for (let key in data) {
    if (data.hasOwnProperty(key)) {
      formData.append(key, data[key])
    }
  }

  headers.set('Content-Type', 'application/x-www-form-urlencoded')

  return { body: formData, headers }
}

我发现文档中没有关于如何发送表单数据的示例,这是非常疯狂的,我不得不在google上搜索很多,直到我找到了如何实现它。

我在登录组件中执行查询:

代码语言:javascript
复制
  const [doLogin, { data }] = useMutation(LOGIN_QUERY, {
    onCompleted: () => {
      console.log("Success")
    },
    onError: () => {
      console.log("Poop")
    }
  })

  const handleSubmit = (event) => {
    event.preventDefault()
    console.log('logging in...')
    doLogin({
      variables: { username, password, formSerializer },
    })
  }

服务器将我登录,返回会话cookie,并包含以下内容的主体:

代码语言:javascript
复制
{
    "data": {
        "user": {
            "id": 1
            "name": "Foobar"
        }
    }
}

当我使用ApolloClient google插件检查缓存状态时,缓存有:

代码语言:javascript
复制
user:null
    id: null
    name: null

以下是我的问题:

  1. 是否需要设置默认状态?
  2. 文档只显示首先被查询的对象上的突变,如果缓存中已经存在对象,那么我只能使用突变更新缓存吗?
  3. 我需要为每一种类型编写解析器吗?
  4. ofc,为什么我会得到空值?
  5. 所有数据是否都需要包装在data对象中,即使对于rest查询也是如此?
  6. 必须将formSerializer作为变量传递给查询,因为我发现这非常难看。

如前所述..。ApolloClient文档是我读过的最糟糕的文档之一。一点也不友好。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-07-12 13:27:36

根据响应变换的说法,阿波罗期望来自REST的响应如下:

代码语言:javascript
复制
{
  "id": 1,
  "name": "Apollo"
}

如果无法控制后端,则可以使用自定义的响应转换器:

代码语言:javascript
复制
responseTransformer: async response => response.json().then(({data}) => data.data?.user)
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/62861231

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档