LoginSignup
0
0

More than 3 years have passed since last update.

ApolloClientでwriteQueryしてもcomponentがupdateされないときの対処法

Last updated at Posted at 2020-05-12

現象

例えば以下では、ユーザが追加されるイベントをSubscribeしており、イベントを受け取ったらキャッシュを書き換えるという処理をしようとしていますが、これだとキャッシュは書き換えられますがcomponentがupdateされません。


const LISTEN_FOR_USERS = gql`
  subscription {
    newUser {
      githubLogin
      name
      avatar
    }
  }
`;

class App extends Component {
  componentDidMount() {
    let { client } = this.props;
    this.listenForUsers = client
      .subscribe({ query: LISTEN_FOR_USERS })
      .subscribe(({ data: { newUser } }) => {
        const data = client.readQuery({ query: ROOT_QUERY });
        data.totalUsers += 1;
        data.allUsers = [...data.allUsers, newUser];
        client.writeQuery({ query: ROOT_QUERY, data });
      });
  }
  ...
}

理由

cacheされたオブジェクトをreadしてそのまま更新すると、変更されたとみなされないからです。
これを防ぐには、以下のようにします。

class App extends Component {
  componentDidMount() {
    let { client } = this.props;
    this.listenForUsers = client
      .subscribe({ query: LISTEN_FOR_USERS })
      .subscribe(({ data: { newUser } }) => {
        // 新たにオブジェクトを作成する
        const data = { ...client.readQuery({ query: ROOT_QUERY }) };
        data.totalUsers += 1;
        data.allUsers = [...data.allUsers, newUser];
        client.writeQuery({ query: ROOT_QUERY, data });
      });
  }
  ...
}

仕組み化

こちらにあるように、InMemoryCache作成時に freezeResults オプションを指定すると、cache を immutable なものとして扱わないとエラーを引き起こすようにできるので、このような失敗をせずにすみます。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0