Как заставить приложение перерисовать после мутации? - PullRequest
0 голосов
/ 13 июня 2019

У меня есть приложение React, созданное с использованием Next.js.Я хочу иметь возможность войти в систему, а затем заставить приложение выполнить повторную визуализацию, чтобы оно попыталось извлечь текущего зарегистрированного пользователя.

Мой _app.js компонент обернут провайдером apollo и имеетполучить также пользовательский запрос:

class MyApp extends App {

  render() {
    const { Component, pageProps, apolloClient } = this.props;
    return (
      <>
        <Container>
          <ApolloProvider client={apolloClient}>
            <Query query={GET_USER} fetchPolicy="network-only" errorPolicy="ignore">
              {({ loading, data, error }) => console.log("rendering app", data) || (
                <>
                  <Component {...pageProps} user={data && data.me} />
                </>
              )}
            </Query>
          </ApolloProvider>
        </Container>
      </>
    );
  }
}

У меня есть форма для входа, которая просто отправляет электронную почту и пароль в мой API, а затем возвращает заголовок токена set-cookie с токеном доступа.

<Mutation 
    mutation={LOGIN}
    onError={error => {
        this.setState({error: "Incorrect email or password"})
    }}
    onCompleted={() => {
        window.location.reload() // temp solution to cause app to re-render
    }}
>
  {(login, {loading}) => (
    <Login 
        {...this.props} 
        login={login} 
        loading={loading} 
        error={error} 
    />
  )}
</Mutation>

Я могу успешно войти в систему, но я ожидал, что кэш Apollo будет записан с пользовательскими данными:

{
  "data": {
    "login": {
      "_id": "abcd1234",
      "accessToken": "abc123",
      "firstName": "First",
      "lastName": "Last",
      "email": "abcd123@b.com",
      "__typename": "User"
    }
  }
}

Когда кэш записывается, я ожидал _app.js /ApolloProvider дети должны сделать заново, так как они получают реквизиты из кэша.

Мой запрос get user должен затем попытаться снова (на этот раз с маркером доступа, установленным в cookie), и пользователь должен быть возвращен (указывая, что пользователь вошел в систему).

Почемумоя мутация не говорит моему приложению повторно выполнить рендеринг onCompleted?

1 Ответ

1 голос
/ 13 июня 2019

Это идеальный сценарий для refetchQueries(): https://www.apollographql.com/docs/angular/features/cache-updates/#refetchqueries

В вашем сценарии вы можете передать эту опору компоненту мутации входа в систему, чтобы повторно запросить запрос GET_USER после входа в систему.Экспортируйте GET USER из вашего _app.js (или куда бы вы его ни перемещали, если вы помещаете его в User Hoc).Затем в вашей регистрационной мутации:

import { GET_USER } from '...'

<Mutation 
    mutation={LOGIN}
    onError={error => {
        this.setState({error: "Incorrect email or password"})
    }}
    onCompleted={() => {
        window.location.reload() // temp solution to cause app to re-render
    }}
    // takes an array of queries to refetch after the mutation is complete
    refetchQueries={[{ query: GET_USER }]} 
>
  {(login, {loading}) => (
    <Login 
        {...this.props} 
        login={login} 
        loading={loading} 
        error={error} 
    />
  )}
</Mutation>

Другой альтернативой является использование метода update, чтобы вручную установить его в кеше, а затем сохранить ссылку на эти данные или извлечь его из кеша с кешем.id, поэтому вам не нужно извлекать больше данных, но refetchQueries идеально подходит для простых мутаций входа в систему, таких как эта, которые не слишком дороги для извлечения.

...