diff --git a/CHANGELOG.md b/CHANGELOG.md index 489d2314f54..4bd9308c691 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -21,6 +21,9 @@ - Make the `client` field of the `MutationResult` type non-optional, since it is always provided.
[@glasser](https://github.com/glasser) in [#6617](https://github.com/apollographql/apollo-client/pull/6617) +- Allow passing an asynchronous `options.renderFunction` to `getMarkupFromTree`.
+ [@richardscarrott](https://github.com/richardscarrott) in [#6576](https://github.com/apollographql/apollo-client/pull/6576) + ## Apollo Client 3.0.2 ## Bug Fixes diff --git a/src/react/ssr/getDataFromTree.ts b/src/react/ssr/getDataFromTree.ts index 4e2b53a143e..9d639827a38 100644 --- a/src/react/ssr/getDataFromTree.ts +++ b/src/react/ssr/getDataFromTree.ts @@ -18,7 +18,9 @@ export function getDataFromTree( export type GetMarkupFromTreeOptions = { tree: React.ReactNode; context?: { [key: string]: any }; - renderFunction?: (tree: React.ReactElement) => string; + renderFunction?: ( + tree: React.ReactElement, + ) => string | PromiseLike; }; export function getMarkupFromTree({ @@ -31,24 +33,26 @@ export function getMarkupFromTree({ }: GetMarkupFromTreeOptions): Promise { const renderPromises = new RenderPromises(); - function process(): Promise | string { + function process(): Promise { // Always re-render from the rootElement, even though it might seem // better to render the children of the component responsible for the // promise, because it is not possible to reconstruct the full context // of the original rendering (including all unknown context provider // elements) for a subtree of the original component tree. const ApolloContext = getApolloContext(); - const html = renderFunction( - React.createElement( - ApolloContext.Provider, - { value: { ...context, renderPromises } }, - tree - ) - ); - return renderPromises.hasPromises() - ? renderPromises.consumeAndAwaitPromises().then(process) - : html; + return new Promise(resolve => { + const element = React.createElement( + ApolloContext.Provider, + { value: { ...context, renderPromises }}, + tree, + ); + resolve(renderFunction(element)); + }).then(html => { + return renderPromises.hasPromises() + ? renderPromises.consumeAndAwaitPromises().then(process) + : html; + }); } return Promise.resolve().then(process);