В поисках решения Дэниел написал, решил это.

тоящее время мы переходим отРеле вРеагировать Аполлон 2.1 и то, что я делаю, кажется подозрительным.

Контекст: Некоторые компоненты должны отображаться только в том случае, если пользователь прошел аутентификацию (через ключ API), поэтому существуетAuthenticator компонент, охраняющий остальную часть дерева.

В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, token }) => {
        if (error) return <div>{error.message}</div>;
        if (token) return <MyComponent token={token} />;
        return <div>Authenticating...</div>;
      }}
    />
  );
}

Если аутентификация прошла успешно,MyComponent оказываетсяAuthentication отправляет мутацию аутентификации на сервер при визуализации / монтировании в первый раз и вызываетоказывать опору соответственно.Authentication.js выглядит так:

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

Этоif (!called) login(); это то, что дает мне паузу. Если я не укажуif (!called)пользовательский интерфейс становится эпилептическим и отправляет тысячи запросов (что имеет смысл, вызываяlogin() причиныrender() перезапустить), но так ли это?

Кажется, чтоQuery компонентный эквивалент отличается тем, что просто рендеринг выдает запрос. и мне интересно, если есть способ применить тот же механизм кMutation, который требует вызова функции mutate как части рендеринга.

Эстафета, эквивалентная фрагменту выше, делает именно то, что реагирует АполлонаQuery делает наMutation:

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

Ответы на вопрос(1)

Ваш ответ на вопрос