В поисках решения Дэниел написал, решил это.
тоящее время мы переходим отРеле вРеагировать Аполлон 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>;
}}
/>
);
}