Skip to content
This repository has been archived by the owner on Apr 13, 2023. It is now read-only.

Reimplement getDataFromTree using ReactDOM.renderToStaticMarkup. #2533

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions Changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,19 @@
refetching. <br/>
[@steelbrain](https://github.com/steelbrain) in [#2493](https://github.com/apollographql/react-apollo/pull/2493)

### Improvements

- Reimplement `getDataFromTree` using `ReactDOM.renderToStaticMarkup` to
make asynchronous server-side rendering compatible with
[React hooks](https://reactjs.org/docs/hooks-intro.html).
Although the rendering function used by `getDataFromTree` defaults to
`renderToStaticMarkup`, any suitable rendering function can be passed as
the optional second argument to `getDataFromTree`, which now returns a
`Promise<string>` that resolves to The HTML rendered in the final pass,
which means calling `renderToString` after `getDataFromTree` may not be
necessary anymore.
[PR #2533](https://github.com/apollographql/react-apollo/pull/2533)

## 2.2.4 (October 2, 2018)

### Bug Fixes
Expand Down
12 changes: 6 additions & 6 deletions examples/ssr/.meteor/packages
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,15 @@

[email protected] # Packages every Meteor app needs to have
[email protected] # Packages for a great mobile UX
mongo@1.5.0 # The database Meteor supports right now
mongo@1.6.0 # The database Meteor supports right now
static-html # Define static page content in .html files
[email protected] # Reactive variable for tracker
[email protected] # Meteor's client-side reactive programming library

standard-minifier-css@1.4.1 # CSS minifier run for production mode
standard-minifier-js@2.3.4 # JS minifier run for production mode
standard-minifier-css@1.5.0 # CSS minifier run for production mode
standard-minifier-js@2.4.0 # JS minifier run for production mode
[email protected] # ECMAScript 5 compatibility for older browsers
ecmascript@0.11.1 # Enable ECMAScript2015+ syntax in app code
shell-server@0.3.1 # Server-side component of the `meteor shell` command
ecmascript@0.12.0 # Enable ECMAScript2015+ syntax in app code
shell-server@0.4.0 # Server-side component of the `meteor shell` command
[email protected]
underscore
underscore@1.0.10
2 changes: 1 addition & 1 deletion examples/ssr/.meteor/release
Original file line number Diff line number Diff line change
@@ -1 +1 @@
METEOR@1.7.0.5
METEOR@1.8
45 changes: 23 additions & 22 deletions examples/ssr/.meteor/versions
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
[email protected]
autoupdate@1.4.1
babel-compiler@7.1.1
babel-runtime@1.2.7
autoupdate@1.5.0
babel-compiler@7.2.1
babel-runtime@1.3.0
[email protected]
[email protected].10
[email protected].11
[email protected]
boilerplate-generator@1.5.0
caching-compiler@1.1.12
boilerplate-generator@1.6.0
caching-compiler@1.2.0
[email protected]
[email protected]
[email protected]
Expand All @@ -16,53 +16,54 @@ [email protected]
[email protected]
[email protected]
[email protected]
dynamic-import@0.4.2
ecmascript@0.11.1
dynamic-import@0.5.0
ecmascript@0.12.1
[email protected]
ecmascript-runtime-client@0.7.2
ecmascript-runtime-client@0.8.0
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
minifier-css@1.3.1
minifier-js@2.3.5
minifier-css@1.4.0
minifier-js@2.4.0
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
npm-mongo@3.0.11
npm-mongo@3.1.1
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
routepolicy@1.0.13
routepolicy@1.1.0
[email protected]
shell-server@0.3.1
shell-server@0.4.0
[email protected]
[email protected]
standard-minifier-css@1.4.1
standard-minifier-js@2.3.4
standard-minifier-css@1.5.1
standard-minifier-js@2.4.0
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
6 changes: 3 additions & 3 deletions examples/ssr/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@
"visualize": "meteor --production --extra-packages bundle-visualizer"
},
"dependencies": {
"@babel/runtime": "7.1.2",
"apollo-cache-inmemory": "^1.2.10",
"apollo-client": "^2.4.2",
"@babel/runtime": "^7.1.2",
"apollo-cache-inmemory": "^1.3.7",
"apollo-client": "^2.4.4",
"apollo-link-http": "^1.5.5",
"apollo-server": "^2.1.0",
"apollo-server-express": "^2.1.0",
Expand Down
3 changes: 2 additions & 1 deletion examples/ssr/server/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,11 @@ export const render = async sink => {
</ApolloProvider>
);

const start = +new Date;
benjamn marked this conversation as resolved.
Show resolved Hide resolved
// Load all data from local server
await getDataFromTree(WrappedApp);

const body = renderToString(WrappedApp);
console.log("server rendering took", new Date - start, "ms");
sink.renderIntoElementById('app', body);
sink.appendToBody(`
<script>
Expand Down
2 changes: 1 addition & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "react-apollo",
"version": "2.2.4",
"version": "2.3.0-beta.1",
"author": "[email protected]",
"browser": "lib/react-apollo.browser.umd.js",
"description": "React data container for Apollo Client",
Expand Down
8 changes: 7 additions & 1 deletion rollup.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,13 @@ export default [
plugins: [
node(),
commonjs({
ignore: ['react', 'apollo-client', 'graphql', 'graphql-tag'],
ignore: [
'react',
'react-dom/server',
'apollo-client',
'graphql',
'graphql-tag',
],
}),
replace({
'process.env.NODE_ENV': JSON.stringify('production'),
Expand Down
14 changes: 10 additions & 4 deletions src/Query.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import { ZenObservable } from 'zen-observable-ts';
import { OperationVariables, GraphqlQueryControls } from './types';
import { parser, DocumentType, IDocumentDefinition } from './parser';
import { getClient } from './component-utils';
import { RenderPromises } from './getDataFromTree';

const shallowEqual = require('fbjs/lib/shallowEqual');
const invariant = require('invariant');
Expand Down Expand Up @@ -101,6 +102,7 @@ export interface QueryProps<TData = any, TVariables = OperationVariables> {
export interface QueryContext {
client?: ApolloClient<Object>;
operations?: Map<string, { query: DocumentNode; variables: any }>;
renderPromises?: RenderPromises;
}

export default class Query<TData = any, TVariables = OperationVariables> extends React.Component<
Expand All @@ -109,6 +111,7 @@ export default class Query<TData = any, TVariables = OperationVariables> extends
static contextTypes = {
client: PropTypes.object,
operations: PropTypes.object,
renderPromises: PropTypes.object,
};

static propTypes = {
Expand Down Expand Up @@ -244,10 +247,13 @@ export default class Query<TData = any, TVariables = OperationVariables> extends
}
}

render() {
const { children } = this.props;
const queryResult = this.getQueryResult();
return children(queryResult);
render(): React.ReactNode {
const { context } = this;
const finish = () => this.props.children(this.getQueryResult());
if (context && context.renderPromises) {
return context.renderPromises.addQueryPromise(this, finish);
}
return finish();
}

private extractOptsFromProps(props: QueryProps<TData, TVariables>) {
Expand Down
2 changes: 2 additions & 0 deletions src/browser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ export * from './withApollo';

export * from './types';

export * from './walkTree';
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we just avoid exporting this? Does anyone actually use walkTree directly (not through getDataFromTree), besides the tests in this repository?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have seen some people using it, but not many. I did a quick GH code search, and can find it being referenced in a couple of cases, but again not many. Maybe we consider dropping the export when we hit 3.0?


// XXX remove in the next breaking semver change (3.0)
const compose = require('lodash.flowright');
export { compose };
Loading