【问题标题】:Apollo + React Router 4 SSR issueApollo + React Router 4 SSR 问题
【发布时间】:2017-08-21 20:21:58
【问题描述】:

不确定这是 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);

...我明白了:

警告:道具类型失败:提供给ApolloProviderarray 类型的无效道具 children,需要单个 ReactElement。 在 ApolloProvider 错误 React.Children.only 期望接收单个 React 元素子元素。

然后翻转,以 React Router 的 &lt;StaticRouter&gt; 为顶部,即:

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

...然后我得到:

&lt;Router&gt; 可能只有一个子元素

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

它在 React Router v3 中也能很好地工作,因为它在 React 层次结构外部进行所有路由匹配,而不是在其内部声明。

【问题讨论】:

    标签: javascript react-router apollo


    【解决方案1】:

    这实际上是一个用户错误。我希望 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);
    

    【讨论】:

      猜你喜欢
      • 2020-08-20
      • 1970-01-01
      • 2016-01-22
      • 2021-01-12
      • 2021-01-28
      • 2020-04-15
      • 2018-04-12
      • 2020-12-17
      • 2018-09-26
      相关资源
      最近更新 更多