Реагировать на Apollo SSR getDataFromTree, не ожидая запроса - PullRequest
2 голосов
/ 08 июня 2019

Я пытаюсь настроить SSR для моего приложения React, которое использует клиент Apollo для запросов graphql к API. Я правильно настроил конфигурацию webpack и приложение Express, и я вижу, как загружаются компоненты. Проблема здесь в том, что getDataFromTree вообще не ждет моего запроса. Он просто возвращает компонент с loading: true, а затем ничего. Я также установил ssrForceFetchDelay, чтобы клиент повторял запросы, но ничего.

Я продолжаю получать window.__APOLLO_STATE__={}. Компоненты очень просты, делают простые запросы и отображают результат.

Это мое экспресс приложение:

    app.use((req, res) => {
     const client = new ApolloClient({
     ssrMode: true,
     link: new HttpLink({
      uri: 'http://localhost:8000/graphql',
      fetch: fetch
     }),
     cache: new InMemoryCache(),
    });
    const app = (
     <ApolloProvider client={client}>
      <Router location={req.url} context={{}}>
        <App client={client}/>
      </Router>
     </ApolloProvider>
    );
   const jsx = extractor.collectChunks(app); // Using loadable

   renderToStringWithData(jsx).then((dataResp) => {   
    const content = dataResp;   
    const state = client.extract(); // Always {}
    const helmet = Helmet.renderStatic();
    const html = ReactDOMServer.renderToStaticMarkup(
      <Html content={content} helmet={helmet} assets={assets} state={state} />,
    );
    res.status(200); res.send(`<!doctype html>${html}`);
    res.end();
    }).catch(err => {
     console.log(`Error thrown`);
    }); 
   });

   app.listen(port, () => {
    console.log(`Server listening on ${port} port`);
   });

Это мой клиентский конфиг Apollo:

const cache = new InMemoryCache().restore(window.__APOLLO_STATE__);
const client = new ApolloClient({
  ssrForceFetchDelay: 300,
  link: links,
  cache: cache,
  connectToDevTools: true,
});

Мое приложение:

const Wrapped = () => {
    console.log(`Inside Wrapped`);
    return (
    <ApolloProvider client={apolloClient}> //The client one
        <Router>
            <App />  /*Only returns 2 basic components */
        </Router>
      </ApolloProvider>
    );
  };

  hydrate(<Wrapped />, document.getElementById('root'));

Я вижу компоненты на странице, но запросы не были загружены, а APOLLO_STATE всегда пуст. Я следовал документации по react-apollo, чтобы настроить это, но я не могу понять, почему эта базовая установка не будет работать. Любые идеи о том, что мне нужно изменить здесь? Спасибо!

HTML-компонент:

import React from 'react';

const Html = ({ content, helmet, assets, state }) => {
  return (
    <html lang="en">
      <head>
        <meta charSet="utf-8" />
        <meta
          name="viewport"
          content="width=device-width, initial-scale=1, shrink-to-fit=no"
        />
        <meta name="theme-color" content="#000000" />
        <link rel="manifest" href="/manifest.json" />
        <link rel="shortcut icon" href="/favicon.ico" />
        {helmet.meta.toComponent()}
        {helmet.title.toComponent()}
        {assets.css &&
          assets.css.map((c, idx) => (
            <link key={idx} href={c} rel="stylesheet" />
          ))}
      </head>

      <body>
        <noscript>You need to enable JavaScript to run this app.</noscript>
        <div id="root" dangerouslySetInnerHTML={{ __html: content }} />
        <script
          dangerouslySetInnerHTML={{
            __html: `window.__APOLLO_STATE__=${JSON.stringify(state).replace(
              /</g,
              '\\u003c',
            )};`,
          }}
        />
        {assets.js &&
          assets.js.map((j, idx) => (
            <script key={idx} src={j} />
          ))}
      </body>
    </html>
  );
};

export default Html;

РЕДАКТИРОВАТЬ: добавлен мой HTML-код компонента

Ссылка на репо с базовым кодом, который работает правильно. Я намереваюсь добавить Loadable к этому, чтобы видеть, является ли это причиной проблемы.

https://github.com/kvnam/gql-ssr-test

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...