¿Cómo ejecutar una mutación en el monte con el componente de mutación React Apollo 2.1?
Actualmente nos estamos mudando deRelé aReaccionar Apolo 2.1 y algo que estoy haciendo parece sospechoso.
Contexto: Algunos componentes solo deben representarse si el usuario está autenticado (a través de una clave API), por lo que hay unAuthenticator
componente que protege el resto del árbol.
EnApp.js
, se usa así (obviamente, todos los fragmentos a continuación son ejemplos 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>;
}}
/>
);
}
Si la autenticación tiene éxito,MyComponent
se procesaAuthentication
envía la mutación de autenticación al servidor cuando se procesa / monta por primera vez y llama alrender prop en consecuencia.Authentication.js
se ve como tal:
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>
);
}
Eseif (!called) login();
es lo que me está dando pausa. Si no especificoif (!called)
, la IU se vuelve epiléptica y envía miles de solicitudes (lo cual tiene sentido, llamandologin()
causasrender()
volver a ejecutar), pero ¿es así como se supone que debe usarse?
Parece que elQuery
componente equivalente difiere en que simplemente al emitirla emite la solicitud. y me pregunto si hay una manera de aplicar el mismo mecanismo paraMutation
, que requiere llamar a la función mutate como parte del render prop.
El equivalente de retransmisión del fragmento anterior hace exactamente lo que React ApolloQuery
hace enMutation
:
// 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>;
}}
/>
);
}