Apollo + React Router 4 SSR 问题

Lee*_*son 1 javascript apollo react-router

不确定这是 React Router v4、React Apollo 客户端还是我的实现的问题。

但是<ApolloProvider>作为顶级 HOC,即:

const ComponentsWithData = await getDataFromTree(
  <ApolloProvider client={apolloClient}>
    <StaticRouter location={ctx.request.url} context={route}>
      <App />
    </StaticRouter>,
  </ApolloProvider>,
);

const html = ReactDOMServer.renderToString(ComponentsWithData);
Run Code Online (Sandbox Code Playgroud)

......我明白了:

警告:无法丙类型:无效支柱children型的array供给ApolloProvider,预期单个ReactElement。在 ApolloProvider 错误 React.Children.only 期望接收单个 React 元素子元素。

并翻转过来,以 React Router<StaticRouter>为顶部,即:

const ComponentsWithData = await getDataFromTree(
  <ApolloProvider client={apolloClient}>
    <StaticRouter location={ctx.request.url} context={route}>
      <App />
    </StaticRouter>,
  </ApolloProvider>,
);
Run Code Online (Sandbox Code Playgroud)

...然后我得到:

A<Router>可能只有一个子元素

渲染在浏览器中工作正常(使用 React Router 的<BrowserRouter>),但在服务器上失败。

由于在 React 层次结构之外进行所有路由匹配,而不是在其内部进行声明,因此它在 React Router v3 中也运行良好。

Lee*_*son 5

这实际上是用户错误。我希望getDataFromTree()返回一个解析为原始组件链的 Promise(使用正确注入的 GraphQL 数据道具),但它实际上只是等待数据准备就绪。

正确的格式是:

const Components = (
  <StaticRouter location={ctx.request.url} context={route}>
    <ApolloProvider client={client}>
      <App />
    </ApolloProvider>
  </StaticRouter>
);

await getDataFromTree(Components);
const html = ReactDOMServer.renderToString(Components);
Run Code Online (Sandbox Code Playgroud)