使用突变响应更新 apollo 客户端

Posted

技术标签:

【中文标题】使用突变响应更新 apollo 客户端【英文标题】:Update apollo client with response of mutation 【发布时间】:2018-12-19 06:38:21 【问题描述】:

我有一个登录组件,它在提交时会调用登录突变并检索用户数据。

当返回用户数据时,我想设置 apollo 客户端状态,但我对如何设置的文档感到困惑:

我的组件如下所示:

const LOGIN = gql`
  mutation login($username: String!, $password: String!) 
    login(username: $username, password: $password) 
      username
      fullName
    
  
`

const Login = () => 
  const onSubmit = (data, login) => 
    login( variables: data )
      .then(response => console.log("response", response))
      .catch(err => console.log("err", err))
  

  return (
    <Mutation 
        mutation=LOGIN
        update=(cache,  data:  login  ) => 

      
    >
      (login, data) => 

        return (
          <Fragment>
            data.loading ? (
              <Spinner />
            ) : (
              <Form buttonLabel="Submit" fields=loginForm onChange=() =>  onSubmit=e => onSubmit(e, login) />
            )

            data.error ? <div>Incorrect username or password</div> : null
          </Fragment>
        )
      
    </Mutation>
  )

如您所见,我的突变中有更新道具,它接收login 参数并具有我想在阿波罗客户端状态中设置的用户数据。

示例here 将响应写入缓存cache.writeQuery,但我不确定这是否是我想要做的。我是否不想像在this example 中那样更新本地数据时写入客户端(而不是缓存)?

mutation 的更新属性似乎只接收缓存参数,所以我不确定是否有任何方法可以访问 client 而不是 cache

如何在 mutate 的更新属性中使用我的突变响应来更新我的 apollo 客户端状态?

编辑:我的客户:

const cache = new InMemoryCache()
const client = new ApolloClient(
  uri: "http://localhost:4000/graphql",
  clientState: 
    defaults: 
      locale: "en-GB",
      agent: null /* <--- update agent */
    ,
    typeDefs: `
      enum Locale 
        en-GB
        fr-FR
        nl-NL
      

      type Query 
        locale: Locale
      
    `
  ,
  cache
)

【问题讨论】:

我不明白您要设置什么“状态”,您链接到的示例用于更新客户端缓存以使用缓存数据进行查询(由于@987654332 现在可能无效@你执行)。您是否尝试在登录后为将来的apollo-client 查询设置某种身份验证上下文? ***.com/q/51081591/8284239 @EdwardSammutAlessi 是的,我正在尝试设置用户数据,以便稍后查询。那么将其写入客户端状态是否正确?如果是这样,我该如何实现? @Stretch0 没有要写入的客户端状态。您需要将该信息存储在其他地方。如果您想在请求中添加Authentication 标头,请考虑使用apollo-link 在发送请求之前对其进行修改。 @EdwardSammutAlessi 也许我很困惑。我已经用我的客户端对象添加了一个编辑,正如你所看到的,我有我的默认值,其中agent 等于 null。当用户登录时,我希望代理设置好。那么我要更新缓存还是客户端? 【参考方案1】:

使用上下文 API

如果您使用ApolloProvider 将组件包装在层次结构中更高的位置

使用ApolloConsumer

const Login = () => 
    const onSubmit = async (data, login, client) => 
        const response = await login( variables: data );

        if (response) 
            client.whatever = response;
        
    ;

    return (
        <ApolloConsumer>
            client => (
                <Mutation mutation=LOGIN>
                    login => <Form onSubmit=e => onSubmit(e, login, client) />
                </Mutation>
            )
        </ApolloConsumer>
    );
;

使用withApollo

const Login = client => 
    const onSubmit = async (data, login) => 
        const response = await login( variables: data );

        if (response) 
            client.whatever = response;
        
    ;

    return (
        <Mutation mutation=LOGIN>
            login => <Form onSubmit=e => onSubmit(e, login) />
        </Mutation>
    );
;

withApollo(Login);

无上下文 API

import  client  from "wherever-you-made-your-client";

然后在那里引用它

【讨论】:

这看起来更像我想要实现的目标。将尝试这个并很快更新。谢谢

以上是关于使用突变响应更新 apollo 客户端的主要内容,如果未能解决你的问题,请参考以下文章

突变后使用订阅和更新创建重复节点 - 使用 Apollo 客户端

Apollo 客户端递归突变

Apollo 客户端突变错误和更新组件

React Apollo 在突变后更新客户端缓存

使用 writeQuery() 更新 Apollo 客户端上的缓存

React-apollo 突变 writeQuery 不更新 ui