¿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>;
      }}
    />
  );
}

Respuestas a la pregunta(1)

Su respuesta a la pregunta