Skip to content

Commit ba2af83

Browse files
avocadowastakentrojanowski
authored andcommitted
feat(getMarkupFromTree): add onBeforeRender handler (#64)
1 parent a0e9e69 commit ba2af83

File tree

2 files changed

+58
-1
lines changed

2 files changed

+58
-1
lines changed

src/__tests__/getMarkupFromTree-test.tsx

Lines changed: 52 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,12 @@ import ApolloClient from 'apollo-client';
22
import { ApolloLink, Observable } from 'apollo-link';
33
import { MockedResponse } from 'apollo-link-mock';
44
import gql from 'graphql-tag';
5-
import * as React from 'react';
5+
import React, {
6+
HTMLAttributes,
7+
ReactElement,
8+
createContext,
9+
useContext,
10+
} from 'react';
611
import { renderToString } from 'react-dom/server';
712

813
import { ApolloProvider } from '../ApolloContext';
@@ -305,3 +310,49 @@ Object {
305310
});
306311
}
307312
);
313+
314+
it('runs onBeforeRender', async () => {
315+
const client = createMockClient();
316+
const context: { headTags: Array<ReactElement<object>> } = { headTags: [] };
317+
const Context = createContext(context);
318+
319+
function Title(props: HTMLAttributes<HTMLTitleElement>) {
320+
const ctx = useContext(Context);
321+
322+
ctx.headTags.push(<title {...props} />);
323+
324+
return null;
325+
}
326+
327+
let step = 0;
328+
329+
await getMarkupFromTree({
330+
onBeforeRender: () => {
331+
switch (++step) {
332+
case 1: {
333+
// First attempt, nothing happened yet.
334+
expect(context.headTags).toHaveLength(0);
335+
break;
336+
}
337+
338+
case 2: {
339+
// Second attempt, we should have populated context.
340+
expect(context.headTags).toHaveLength(1);
341+
break;
342+
}
343+
}
344+
},
345+
renderFunction: renderToString,
346+
tree: (
347+
<>
348+
<Title>Hello!</Title>
349+
<UserDetailsWrapper client={client} />
350+
</>
351+
),
352+
});
353+
354+
// Second attempt should create duplicates.
355+
expect(context.headTags).toHaveLength(2);
356+
357+
expect.assertions(3);
358+
});

src/getMarkupFromTree.tsx

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,17 +4,23 @@ import { isPromiseLike } from './utils';
44

55
export interface GetMarkupFromTreeOptions {
66
tree: React.ReactNode;
7+
onBeforeRender?: () => void;
78
renderFunction: (tree: React.ReactElement<object>) => string;
89
}
910

1011
export function getMarkupFromTree({
1112
tree,
13+
onBeforeRender,
1214
renderFunction,
1315
}: GetMarkupFromTreeOptions): Promise<string> {
1416
const ssrManager = createSSRManager();
1517

1618
function process(): string | Promise<string> {
1719
try {
20+
if (onBeforeRender) {
21+
onBeforeRender();
22+
}
23+
1824
const html = renderFunction(
1925
<SSRContext.Provider value={ssrManager}>{tree}</SSRContext.Provider>
2026
);

0 commit comments

Comments
 (0)