写入缓存时,Apollo 客户端链接状态“ 中缺少字段”?

Posted

技术标签:

【中文标题】写入缓存时,Apollo 客户端链接状态“ 中缺少字段”?【英文标题】:Apollo client link state "Missing field in " when writing to cache?写入缓存时,Apollo 客户端链接状态“ 中缺少字段”? 【发布时间】:2018-07-08 02:05:15 【问题描述】:

我正在使用 Apollo 客户端、Graphcool 和 React。我有一个有效的登录表单,但我需要在用户登录时更新 UI,并且我需要在不同的组件中发生这种情况。

看来 apollo-link-state 是解决这个问题的方法。我下面的代码似乎可以工作,但我收到了这个错误:

Missing field CurrentUserIsLoggedIn in in writeToStore.js

我的 Apollo 客户端设置:

import React from 'react';
import ReactDOM from 'react-dom';

// Apollo
import  ApolloProvider  from 'react-apollo';
import  ApolloClient  from 'apollo-client';
import  HttpLink  from 'apollo-link-http';
import  InMemoryCache  from 'apollo-cache-inmemory';
import  ApolloLink, split  from 'apollo-link';
import  withClientState  from 'apollo-link-state';
import  WebSocketLink  from 'apollo-link-ws';
import  getMainDefinition  from 'apollo-utilities';

// Components
import LoginTest from './components/App/LoginTest';

const wsLink = new WebSocketLink(
    uri: `wss://subscriptions.graph.cool/v1/XXX`,
    options: 
        reconnect: true,
    ,
);

// __SIMPLE_API_ENDPOINT__ looks like: 'https://api.graph.cool/simple/v1/__SERVICE_ID__'
const httpLink = new HttpLink(
    uri: 'https://api.graph.cool/simple/v1/XXX',
);

// auth
const middlewareAuthLink = new ApolloLink((operation, forward) => 
    const token = localStorage.getItem('auth-token');
    const authorizationHeader = token ? `Bearer $token` : null;
    operation.setContext(
        headers: 
            authorization: authorizationHeader,
        ,
    );
    return forward(operation);
);

const cache = new InMemoryCache();

const defaultState = 
    CurrentUserIsLoggedIn: 
        __typename: 'CurrentUserIsLoggedIn',
        value: false,
    ,
;

const stateLink = withClientState(
    cache,
    defaults: defaultState,
    resolvers: 
        Mutation: 
            CurrentUserIsLoggedIn: (_, args) => 
                const data = 
                    CurrentUserIsLoggedIn: 
                        __typename: 'CurrentUserIsLoggedIn',
                        value: args.value,
                    ,
                ;
                cache.writeData( data );
            ,
        ,
    ,
);

const client = new ApolloClient(
    cache,
    link: ApolloLink.from([
        stateLink,
        middlewareAuthLink,

        split(
            // split based on operation type
            ( query ) => 
                const  kind, operation  = getMainDefinition(query);
                return kind === 'OperationDefinition' && operation === 'subscription';
            ,
            wsLink,
            httpLink,
        ),
    ]),
);

ReactDOM.render(
    <ApolloProvider client=client>
        <LoginTest />
    </ApolloProvider>,
    document.getElementById('root'),
);

LoginTest.js:

import React from 'react';

import  graphql, compose  from 'react-apollo';
import gql from 'graphql-tag';

import App from './App';

const LoginTest = props => 
    if (props.LoginServerQuery.loading) return <p>Loading...</p>;

    // If the server tells us the user is logged in
    if (props.LoginServerQuery.loggedInUser) 
        // Then set the local logged in state to true
        props.CurrentUserIsLoggedInMutation(
            variables: 
                value: true,
            ,
        );
    

    return <App />;
;

const CurrentUserIsLoggedInMutation = gql`
    mutation CurrentUserIsLoggedInMutation($value: Boolean) 
        CurrentUserIsLoggedIn(value: $value) @client 
            value
        
    
`;

const LoginServerQuery = gql`
    query LoginServerQuery 
        loggedInUser 
            id
        
    
`;

const LoginTestQuery = compose(
    graphql(LoginServerQuery,  name: 'LoginServerQuery' ),
    graphql(CurrentUserIsLoggedInMutation, 
        name: 'CurrentUserIsLoggedInMutation',
    ),
)(LoginTest);

export default LoginTestQuery;

【问题讨论】:

你能指定错误发生的行吗? @Luke Ive 将错误的屏幕截图上传到我的问题。我不知道行号有多大帮助。 writeToStore.js,这个文件的代码在哪里? 我猜这是由 cache.writeData 调用的,但我不确定。 所以这里:***.com/questions/48005732/… some1 必须在他的变异方法中创建一个 return 语句,也许在你的变异方法中添加 return 语句,因为你没有 【参考方案1】:

目前,apollo-link-state 要求您在解析器函数中返回任何结果。也可以是null。 This might be changed in the future.

【讨论】:

此消息的另一个可能原因是缺少@client 指令【参考方案2】:
const stateLink = withClientState(
cache,
defaults: defaultState,
resolvers: 
    Mutation: 
        CurrentUserIsLoggedIn: (_, args) => 
            const data = 
                CurrentUserIsLoggedIn: 
                    __typename: 'CurrentUserIsLoggedIn',
                    value: args.value,
                ,
            ;
            cache.writeData( data );
            return data;
        ,
    ,
,

尝试在您的突变中添加一个返回语句。类似的问题在这里发生了不同的功能:apollo-link-state cache.writedata results in Missing field warning

【讨论】:

我现在实际上遇到了 2 个错误! 中的缺失字段值和 中的缺失字段 __typename 均位于 writeToStore.js:111 @Evans 你是怎么解决这个问题的?

以上是关于写入缓存时,Apollo 客户端链接状态“ 中缺少字段”?的主要内容,如果未能解决你的问题,请参考以下文章

刷新页面时,apollo-state-link 不在缓存中保存状态

使用 Apollo 链路状态缓存实现客户端过滤

Apollo GraphQL,有没有办法在查询期间操作正在写入缓存的数据?

Apollo 客户端持久缓存不起作用

在查询上遇到子选择,但是存储没有对象引用 Apollo Link State

如何在不丢失“this”上下文的情况下从 React 组件中写入 apollo 缓存