Skip to content

Commit

Permalink
[change] Configure hydration using AppRegistry.runApplication()
Browse files Browse the repository at this point in the history
Client-side hydration of server-rendered HTML now requires that `hydrate` is explicitly set in the `appParams` passed to `AppRegistry.runApplication()`.

Fix #1374
  • Loading branch information
necolas committed Nov 13, 2019
1 parent e4ed0fd commit afb8d3b
Show file tree
Hide file tree
Showing 4 changed files with 31 additions and 18 deletions.
10 changes: 6 additions & 4 deletions packages/docs/src/apis/AppRegistry/AppRegistry.stories.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -76,15 +76,17 @@ AppRegistry.registerRunnable('MyApp', (appParams) => { ... });
### runApplication(appKey, appParams)
Runs the application that was registered under `appKey`. The `appParameters` must
include the `rootTag` into which the application is rendered, and optionally any
`initialProps` or render callback.
Runs the application that was registered under `appKey`. The `appParameters`
must include the `rootTag` into which the application is rendered, and
optionally any `initialProps` or render callback. If the client should hydrate
server-rendered HTML, set `hydrate` to `true`.
```js
AppRegistry.runApplication('MyApp', {
callback: () => { console.log('React rendering has finished') },
hydrate: true,
initialProps: {},
rootTag: document.getElementById('react-root'),
callback: () => { console.log('React rendering has finished') }
})
```
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,19 +73,23 @@ describe('AppRegistry', () => {
});

describe('runApplication', () => {
test('callback after render', () => {
// setup
const rootTag = document.createElement('div');
let rootTag;

beforeEach(() => {
rootTag = document.createElement('div');
rootTag.id = 'react-root';
document.body.appendChild(rootTag);
});

afterEach(() => {
document.body.removeChild(rootTag);
});

test('callback after render', () => {
const callback = jest.fn();
AppRegistry.registerComponent('App', () => NoopComponent);
AppRegistry.runApplication('App', { initialProps: {}, rootTag, callback });
expect(callback).toHaveBeenCalledTimes(1);

// cleanup
document.body.removeChild(rootTag);
});
});
});
9 changes: 6 additions & 3 deletions packages/react-native-web/src/exports/AppRegistry/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -63,10 +63,13 @@ export default class AppRegistry {
run: appParameters =>
renderApplication(
componentProviderInstrumentationHook(componentProvider),
appParameters.initialProps || emptyObject,
appParameters.rootTag,
wrapperComponentProvider && wrapperComponentProvider(appParameters),
appParameters.callback
appParameters.callback,
{
hydrate: appParameters.hydrate || false,
initialProps: appParameters.initialProps || emptyObject,
rootTag: appParameters.rootTag
}
)
};
return appKey;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,19 @@ import render from '../render';
import styleResolver from '../StyleSheet/styleResolver';
import React, { type ComponentType } from 'react';

const renderFn = process.env.NODE_ENV !== 'production' ? render : hydrate;

export default function renderApplication<Props: Object>(
RootComponent: ComponentType<Props>,
initialProps: Props,
rootTag: any,
WrapperComponent?: ?ComponentType<*>,
callback?: () => void
callback?: () => void,
options: {
hydrate: boolean,
initialProps: Props,
rootTag: any
}
) {
const { hydrate: shouldHydrate, initialProps, rootTag } = options;
const renderFn = shouldHydrate ? hydrate : render;

invariant(rootTag, 'Expect to have a valid rootTag, instead got ', rootTag);

renderFn(
Expand Down

0 comments on commit afb8d3b

Please sign in to comment.