From d65c92eea9e5a82224ee257e732ef2ee2341e875 Mon Sep 17 00:00:00 2001 From: Nicolas Gallagher Date: Tue, 22 Nov 2016 14:28:30 -0800 Subject: [PATCH] [change] prepare for react-dom@15.4.0 Don't depend directly on the 'react-dom' module as it will be prebuilt in 15.4. Leave server-side rendering to 'react-dom/server'. --- docs/apis/AppRegistry.md | 11 +++----- docs/guides/rendering.md | 25 ++++++++++++++----- .../__tests__/renderApplication-test.js | 10 ++++---- src/apis/AppRegistry/index.js | 14 +++++------ src/apis/AppRegistry/renderApplication.js | 13 +++++----- src/components/ScrollView/index.js | 6 ++--- src/core.js | 9 +++---- src/index.js | 10 +++----- src/modules/NativeMethodsMixin/index.js | 14 +++++------ src/modules/ScrollResponder/index.js | 6 ++--- src/modules/findNodeHandle/index.js | 3 +-- webpack.config.js | 10 ++++++++ 12 files changed, 71 insertions(+), 60 deletions(-) diff --git a/docs/apis/AppRegistry.md b/docs/apis/AppRegistry.md index f8cf14f0..554904b1 100644 --- a/docs/apis/AppRegistry.md +++ b/docs/apis/AppRegistry.md @@ -13,14 +13,11 @@ into `runApplication`. These should always be used as a pair. ## Methods -(web) static **prerenderApplication**(appKey:string, appParameters: object) +(web) static **getApplication**(appKey:string, appParameters: object) -Renders the given application to an HTML string. Use this for server-side -rendering. Return object is of type `{ html: string; style: string; -styleElement: ReactComponent }`. `html` is the prerendered HTML, `style` is the -prerendered style sheet, and `styleElement` is a React Component. It's -recommended that you use `styleElement` to render the style sheet in an app -shell. +Returns the given application element. Use this for server-side rendering. +Return object is of type `{ element: ReactElement; stylesheet: ReactElement }`. +It's recommended that you use `sheetsheet` to render the style sheet in an app static **registerConfig**(config: Array) diff --git a/docs/guides/rendering.md b/docs/guides/rendering.md index 8c94df83..dfc181f0 100644 --- a/docs/guides/rendering.md +++ b/docs/guides/rendering.md @@ -43,12 +43,7 @@ import ReactNative from 'react-native' // component that renders the app const AppHeaderContainer = (props) => { /* ... */ } -// DOM render ReactNative.render(, document.getElementById('react-app-header')) - -// Server render -ReactNative.renderToString() -ReactNative.renderToStaticMarkup() ``` Rendering using the `AppRegistry`: @@ -63,7 +58,6 @@ const AppContainer = (props) => { /* ... */ } // register the app AppRegistry.registerComponent('App', () => AppContainer) -// DOM render AppRegistry.runApplication('App', { initialProps: {}, rootTag: document.getElementById('react-app') @@ -72,3 +66,22 @@ AppRegistry.runApplication('App', { // prerender the app const { html, styleElement } = AppRegistry.prerenderApplication('App', { initialProps }) ``` + +## Server-side rendering + +Rendering using the `AppRegistry`: + +``` +import ReactDOMServer from 'react-dom/server' +import ReactNative, { AppRegistry } from 'react-native' + +// component that renders the app +const AppContainer = (props) => { /* ... */ } + +// register the app +AppRegistry.registerComponent('App', () => AppContainer) + +// prerender the app +const { element, stylesheet } = AppRegistry.getApplication('App', { initialProps }); +const initialHTML = ReactDOMServer.renderToString(element); + ``` diff --git a/src/apis/AppRegistry/__tests__/renderApplication-test.js b/src/apis/AppRegistry/__tests__/renderApplication-test.js index 210a4d57..c307bf37 100644 --- a/src/apis/AppRegistry/__tests__/renderApplication-test.js +++ b/src/apis/AppRegistry/__tests__/renderApplication-test.js @@ -1,15 +1,15 @@ /* eslint-env jasmine, jest */ -import { prerenderApplication } from '../renderApplication'; +import { getApplication } from '../renderApplication'; import React from 'react'; const component = () =>
; describe('apis/AppRegistry/renderApplication', () => { - test('prerenderApplication', () => { - const { html, styleElement } = prerenderApplication(component, {}); + test('getApplication', () => { + const { element, stylesheet } = getApplication(component, {}); - expect(html.indexOf('
-1).toBeTruthy(); - expect(styleElement.type).toEqual('style'); + expect(element).toBeTruthy(); + expect(stylesheet.type).toEqual('style'); }); }); diff --git a/src/apis/AppRegistry/index.js b/src/apis/AppRegistry/index.js index 0861e780..bec7bc21 100644 --- a/src/apis/AppRegistry/index.js +++ b/src/apis/AppRegistry/index.js @@ -8,7 +8,7 @@ import { Component } from 'react'; import invariant from 'fbjs/lib/invariant'; -import ReactDOM from 'react-dom'; +import { unmountComponentAtNode } from 'react/lib/ReactMount'; import renderApplication, { prerenderApplication } from './renderApplication'; const runnables = {}; @@ -29,20 +29,20 @@ class AppRegistry { return Object.keys(runnables); } - static prerenderApplication(appKey: string, appParameters?: Object): string { + static getApplication(appKey: string, appParameters?: Object): string { invariant( - runnables[appKey] && runnables[appKey].prerender, + runnables[appKey] && runnables[appKey].getApplication, `Application ${appKey} has not been registered. ` + 'This is either due to an import error during initialization or failure to call AppRegistry.registerComponent.' ); - return runnables[appKey].prerender(appParameters); + return runnables[appKey].getApplication(appParameters); } static registerComponent(appKey: string, getComponentFunc: ComponentProvider): string { runnables[appKey] = { - run: ({ initialProps, rootTag }) => renderApplication(getComponentFunc(), initialProps, rootTag), - prerender: ({ initialProps } = {}) => prerenderApplication(getComponentFunc(), initialProps) + getApplication: ({ initialProps } = {}) => getApplication(getComponentFunc(), initialProps), + run: ({ initialProps, rootTag }) => renderApplication(getComponentFunc(), initialProps, rootTag) }; return appKey; } @@ -85,7 +85,7 @@ class AppRegistry { } static unmountApplicationComponentAtRootTag(rootTag) { - ReactDOM.unmountComponentAtNode(rootTag); + unmountComponentAtNode(rootTag); } } diff --git a/src/apis/AppRegistry/renderApplication.js b/src/apis/AppRegistry/renderApplication.js index ce1a42b0..37f8391e 100644 --- a/src/apis/AppRegistry/renderApplication.js +++ b/src/apis/AppRegistry/renderApplication.js @@ -7,7 +7,7 @@ */ import invariant from 'fbjs/lib/invariant'; -import ReactDOM from 'react-dom'; +import { render } from 'react/lib/ReactMount'; import ReactDOMServer from 'react-dom/server'; import ReactNativeApp from './ReactNativeApp'; import StyleSheet from '../../apis/StyleSheet'; @@ -23,17 +23,16 @@ export default function renderApplication(RootComponent: Component, initialProps rootTag={rootTag} /> ); - ReactDOM.render(component, rootTag); + render(component, rootTag); } -export function prerenderApplication(RootComponent: Component, initialProps: Object): string { - const component = ( +export function getApplication(RootComponent: Component, initialProps: Object): Object { + const element = ( ); - const html = ReactDOMServer.renderToString(component); - const styleElement = StyleSheet.render(); - return { html, styleElement }; + const stylesheet = StyleSheet.render(); + return { element, stylesheet }; } diff --git a/src/components/ScrollView/index.js b/src/components/ScrollView/index.js index 4fc32c5a..6e2e0e5d 100644 --- a/src/components/ScrollView/index.js +++ b/src/components/ScrollView/index.js @@ -7,8 +7,8 @@ */ import dismissKeyboard from '../../modules/dismissKeyboard'; +import findNodeHandle from '../../modules/findNodeHandle'; import invariant from 'fbjs/lib/invariant'; -import ReactDOM from 'react-dom'; import ScrollResponder from '../../modules/ScrollResponder'; import ScrollViewBase from './ScrollViewBase'; import StyleSheet from '../../apis/StyleSheet'; @@ -55,11 +55,11 @@ const ScrollView = React.createClass({ }, getScrollableNode(): any { - return ReactDOM.findDOMNode(this._scrollViewRef); + return findNodeHandle(this._scrollViewRef); }, getInnerViewNode(): any { - return ReactDOM.findDOMNode(this._innerViewRef); + return findNodeHandle(this._innerViewRef); }, /** diff --git a/src/core.js b/src/core.js index 4c7eb173..c72eb1a0 100644 --- a/src/core.js +++ b/src/core.js @@ -1,6 +1,5 @@ import findNodeHandle from './modules/findNodeHandle'; -import ReactDOM from 'react-dom'; -import ReactDOMServer from 'react-dom/server'; +import { render, unmountComponentAtNode } from 'react/lib/ReactMount'; // APIs import I18nManager from './apis/I18nManager'; @@ -14,10 +13,8 @@ import View from './components/View'; const ReactNativeCore = { findNodeHandle, - render: ReactDOM.render, - renderToStaticMarkup: ReactDOMServer.renderToStaticMarkup, - renderToString: ReactDOMServer.renderToString, - unmountComponentAtNode: ReactDOM.unmountComponentAtNode, + render, + unmountComponentAtNode, // APIs I18nManager, StyleSheet, diff --git a/src/index.js b/src/index.js index cbc0da9c..a3844248 100644 --- a/src/index.js +++ b/src/index.js @@ -1,6 +1,5 @@ import findNodeHandle from './modules/findNodeHandle'; -import ReactDOM from 'react-dom'; -import ReactDOMServer from 'react-dom/server'; +import { render, unmountComponentAtNode } from 'react/lib/ReactMount'; // APIs import Animated from './apis/Animated'; @@ -47,11 +46,8 @@ import PointPropType from './propTypes/PointPropType'; const ReactNative = { // top-level API findNodeHandle, - render: ReactDOM.render, - unmountComponentAtNode: ReactDOM.unmountComponentAtNode, - // web-only - renderToStaticMarkup: ReactDOMServer.renderToStaticMarkup, - renderToString: ReactDOMServer.renderToString, + render, + unmountComponentAtNode, // APIs Animated, diff --git a/src/modules/NativeMethodsMixin/index.js b/src/modules/NativeMethodsMixin/index.js index 6de1f12e..3e2e248f 100644 --- a/src/modules/NativeMethodsMixin/index.js +++ b/src/modules/NativeMethodsMixin/index.js @@ -7,7 +7,7 @@ */ import { Component } from 'react'; -import ReactDOM from 'react-dom'; +import findNodeHandle from '../findNodeHandle'; import UIManager from '../../apis/UIManager'; type MeasureInWindowOnSuccessCallback = ( @@ -38,7 +38,7 @@ const NativeMethodsMixin = { * Removes focus from an input or view. This is the opposite of `focus()`. */ blur() { - UIManager.blur(ReactDOM.findDOMNode(this)); + UIManager.blur(findNodeHandle(this)); }, /** @@ -46,7 +46,7 @@ const NativeMethodsMixin = { * The exact behavior triggered will depend the type of view. */ focus() { - UIManager.focus(ReactDOM.findDOMNode(this)); + UIManager.focus(findNodeHandle(this)); }, /** @@ -54,7 +54,7 @@ const NativeMethodsMixin = { */ measure(callback: MeasureOnSuccessCallback) { UIManager.measure( - ReactDOM.findDOMNode(this), + findNodeHandle(this), mountSafeCallback(this, callback) ); }, @@ -76,7 +76,7 @@ const NativeMethodsMixin = { */ measureInWindow(callback: MeasureInWindowOnSuccessCallback) { UIManager.measureInWindow( - ReactDOM.findDOMNode(this), + findNodeHandle(this), mountSafeCallback(this, callback) ); }, @@ -90,7 +90,7 @@ const NativeMethodsMixin = { onFail: () => void /* currently unused */ ) { UIManager.measureLayout( - ReactDOM.findDOMNode(this), + findNodeHandle(this), relativeToNativeNode, mountSafeCallback(this, onFail), mountSafeCallback(this, onSuccess) @@ -102,7 +102,7 @@ const NativeMethodsMixin = { */ setNativeProps(nativeProps: Object) { UIManager.updateView( - ReactDOM.findDOMNode(this), + findNodeHandle(this), nativeProps, this ); diff --git a/src/modules/ScrollResponder/index.js b/src/modules/ScrollResponder/index.js index 242119c5..5f0bf100 100644 --- a/src/modules/ScrollResponder/index.js +++ b/src/modules/ScrollResponder/index.js @@ -13,9 +13,9 @@ 'use strict'; var Dimensions = require('../../apis/Dimensions'); +var findNodeHandle = require('../findNodeHandle'); var Platform = require('../../apis/Platform'); var React = require('react'); -var ReactDOM = require('react-dom'); // var Subscribable = require('../Subscribable'); var TextInputState = require('../../components/TextInput/TextInputState'); var UIManager = require('../../apis/UIManager'); @@ -356,7 +356,7 @@ var ScrollResponderMixin = { scrollResponderGetScrollableNode: function(): any { return this.getScrollableNode ? this.getScrollableNode() : - ReactDOM.findDOMNode(this); + findNodeHandle(this); }, /** @@ -423,7 +423,7 @@ var ScrollResponderMixin = { this.preventNegativeScrollOffset = !!preventNegativeScrollOffset; UIManager.measureLayout( nodeHandle, - ReactDOM.findDOMNode(this.getInnerViewNode()), + findNodeHandle(this.getInnerViewNode()), this.scrollResponderTextInputFocusError, this.scrollResponderInputMeasureAndScrollToKeyboard ); diff --git a/src/modules/findNodeHandle/index.js b/src/modules/findNodeHandle/index.js index b41b377c..9db6b9c3 100644 --- a/src/modules/findNodeHandle/index.js +++ b/src/modules/findNodeHandle/index.js @@ -1,3 +1,2 @@ -import ReactDOM from 'react-dom'; -const findNodeHandle = ReactDOM.findDOMNode; +import findNodeHandle from 'react/lib/findDOMNode'; export default findNodeHandle; diff --git a/webpack.config.js b/webpack.config.js index 363b1130..1ff897a2 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -8,6 +8,16 @@ module.exports = { entry: { main: DIST_DIRECTORY }, + externals: [ + { + react: { + root: 'React', + commonjs2: 'react', + commonjs: 'react', + amd: 'react' + } + } + ], output: { filename: 'ReactNative.js', library: 'ReactNative',