Como executar uma mutação em montagem com o componente Mutation do React Apollo 2.1?
No momento, estamos saindo deRetransmissão paraReact Apollo 2.1 e algo que estou fazendo parece suspeito.
Contexto: Alguns componentes devem ser renderizados apenas se o usuário estiver autenticado (por meio de uma chave de API), para que exista umAuthenticator
componente que guarda o resto da árvore.
NoApp.js
, é usado assim (obviamente todos os snippets abaixo são exemplos mínimos):
import React from 'react';
import Authenticator from './Authenticator';
import MyComponent from './MyComponent';
export default function App({ apiKey }) {
return (
<Authenticator apiKey={apiKey}
render={({ error, token }) => {
if (error) return <div>{error.message}</div>;
if (token) return <MyComponent token={token} />;
return <div>Authenticating...</div>;
}}
/>
);
}
Se a autenticação for bem-sucedida,MyComponent
é processado.Authentication
envia a mutação de autenticação para o servidor quando renderizada / montada pela primeira vez e chama orender prop adequadamente.Authentication.js
parece assim:
import gql from 'graphql-tag';
import React from 'react';
import { Mutation } from 'react-apollo';
const AUTH_MUTATION = gql`mutation Login($apiKey: String!) {
login(apiKey: $apiKey) {
token
}
}`;
export default function Authenticator({ apiKey, render }) {
return (
<Mutation mutation={AUTH_MUTATION} variables={{ apiKey }}>
{(login, { data, error, called }) => {
if (!called) login(); // ⚠️ This seems sketchy ⚠️
const token = (data && data.login.token) || undefined;
return render({ error, token });
}}
</Mutation>
);
}
Naquelaif (!called) login();
é o que está me dando uma pausa. Se eu não especificarif (!called)
, a interface do usuário se torna epilética e envia milhares de solicitações (o que faz sentido, chamandologin()
causasrender()
para executar novamente), mas é assim que deve ser usado?
Parece que oQuery
equivalente de componente difere na simples renderização que emite a solicitação. e eu estou querendo saber se existe uma maneira de aplicar o mesmo mecanismo paraMutation
, que exige chamar a função mutate como parte do suporte de renderização.
O equivalente de retransmissão do snippet acima faz exatamente o que o React Apollo'sQuery
faz emMutation
:
// Authentication.js
import React from 'react';
import { graphql, QueryRenderer } from 'react-relay';
import { Environment } from 'relay-runtime';
// Hiding out all the `Environment`-related boilerplate
const environment = return new Environment(/* ... */);
const AUTH_MUTATION = graphql`mutation Login($apiKey: String!) {
login(apiKey: $apiKey) {
token
}
}`;
export default function Authenticator({ apiKey, render }) {
return (
<QueryRenderer query={AUTH_MUTATION} variables={{ apiKey }}
render={render}
/>
);
}
// App.js
import React from 'react';
import Authenticator from './Authenticator';
import MyComponent from './MyComponent';
export default function App({ apiKey }) {
return (
<Authenticator apiKey={apiKey}
render={({ error, props }) => {
if (error) return <div>{error.message}</div>;
if (props) return <MyComponent token={props.loginAPI.token)} />;
return <div>Authenticating...</div>;
}}
/>
);
}