web-dev-qa-db-ja.com

Apolloクライアントでログアウト後にストアをリセット

反応アポロアプリケーションでログアウトした後、ストアをリセットしようとしています。

そこで、ボタンをクリックしたときに呼び出される(そして 'onDisconnect'プロップによって渡される) "logout"というメソッドを作成しました。

それを行うために、私はこの例に従ってみました: https://www.apollographql.com/docs/react/recipes/authentication.html

しかし、私の場合、LayoutComponentをHOCとして使用します(graphQLクエリがありません)。

これが私のコンポーネントです:

import React, {Component} from 'react';
import { withApollo, graphql } from 'react-apollo';
import { ApolloClient } from 'apollo-client';

import AppBar from 'material-ui/AppBar';
import Sidebar from 'Sidebar/Sidebar';
import RightMenu from 'RightMenu/RightMenu';

class Layout extends Component {
constructor(props) {
    super(props);        
}

logout = () => {
    client.resetStore();
    alert("YOUHOU");
}

render() {
    return (
        <div>
            <AppBar title="myApp" iconElementRight={<RightMenu onDisconnect={ this.logout() } />} />
        </div>
    );
}
}

export default withApollo(Layout);

ここでの問題は、「クライアント」が定義されておらず、適切にログアウトできないことです。この状況に対処するのに役立つアイデアや、apolloクライアントからログアウトするための例/ベストプラクティスはありますか?

事前に感謝

9
Putxe

キャッシュをクリアする必要があり、アクティブなクエリをすべてフェッチしたくない場合は、次のコマンドを使用できます。

client.cache.reset()

clientはApolloクライアントです。

これはonResetStoreイベントをトリガーしないことに注意してください。

11
anthonator

client.resetStore()は実際にはストアをリセットしません。すべてのアクティブなクエリを再フェッチします

上記の文は非常に正しいです。

ログアウトに関連する問題も抱えていました。 client.resetStore()を使用すると、保留中のクエリがすべて再取得されるため、ユーザーをログアウトし、ログアウト後にセッショントークンを削除すると、認証エラーが発生します。

私はこの問題を解決するために以下のアプローチを使用しました-

<Mutation
    mutation={LOGOUT_MUTATION} 
                onCompleted={()=> {
                  sessionStorage.clear()
                  client.clearStore().then(() => {
                    client.resetStore();
                    history.Push('/login')
                  });
                }}
              >
                {logout => (
                  <button
                    onClick={() => {
                      logout();
                    }}
                  >
                    Logout <span>{user.userName}</span>
                  </button>
                )}
              </Mutation>

重要な部分はこの機能です-

onCompleted={()=> {
                  sessionStorage.clear(); // or localStorage
                  client.clearStore().then(() => {
                    client.resetStore();
                    history.Push('/login') . // redirect user to login page
                  });
                }}
7
WitVault

あなたはとても近くにいました!

client.resetStore()の代わりにthis.props.client.resetStore()である必要があります

withApollo() は、ApolloClientのインスタンスをクライアントプロップとして渡す新しいコンポーネントを作成します。

import { withApollo } from 'react-apollo';

class Layout extends Component {
  ...
  logout = () => {
    this.props.client.resetStore();
    alert("YOUHOU");
  }
  ...
}

export default withApollo(Layout);

resetStoreclearStoreの違いがわからない場合:

resetStore()

キャッシュをクリアし、アクティブなクエリをすべて再実行して、ストア全体をリセットします。これにより、このメソッドを呼び出す前の時点からストアにデータが残っていないことが保証されます。

clearStore()

ストアからすべてのデータを削除します。 resetStoreとは異なり、clearStoreはアクティブなクエリを再フェッチしません。

3
JSON C11