Skip to content

Commit

Permalink
Add deprecation warnings for split of the react and react-native pack…
Browse files Browse the repository at this point in the history
…ages

Summary:This adds deprecation warnings that correspond to what React 0.14 did for the web.

I.e. `React.render` -> `ReactNative.render` but also `ReactNative.createClass` -> `React.createClass`.

This hopefully means that it will become easier and more idiomatic to write components that are decoupled from the react-native package.

It will be clear when you take on react-native as a dependency such as when using findNodeHandle.

This codemod is a little more invasive for React Native because the common stuff often used the `react-native` package. For web only the uncommon stuff needed to move.

Reviewed By: spicyj

Differential Revision: D3148860

fb-gh-sync-id: d87628d2089a2e012ad6ad50dd0a20ccec5e6c45
fbshipit-source-id: d87628d2089a2e012ad6ad50dd0a20ccec5e6c45
  • Loading branch information
sebmarkbage authored and Facebook Github Bot 2 committed Apr 9, 2016
1 parent a80dd9a commit 2eafcd4
Show file tree
Hide file tree
Showing 4 changed files with 145 additions and 119 deletions.
31 changes: 30 additions & 1 deletion Libraries/ReactNative/React.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,33 @@
*/
'use strict';

module.exports = require('ReactNative');
const ReactIsomorphic = require('ReactIsomorphic');
const ReactNativeImpl = require('ReactNativeImpl');
const warning = require('warning');

This comment has been minimized.

Copy link
@bestander

bestander Apr 9, 2016

Contributor

OSS react native needs this to be `require('fbjs/lib/warning').
OSS trunk got broken :(
https://circleci.com/gh/facebook/react-native/4990


const React = { ...ReactIsomorphic };

const dedupe = {};

for (const key in ReactNativeImpl) {
React[key] = ReactNativeImpl[key];
if (__DEV__) {
Object.defineProperty(React, key, {
get: function() {
warning(
dedupe[key],
'React.' + key + ' is deprecated. Use ReactNative.' + key +
' from the "react-native" package instead.'
);
dedupe[key] = true;
return ReactNativeImpl[key];
},
set: function(value) {
// Useful for hacky solutions like createExamplePage.
ReactNativeImpl[key] = value;
},
});
}
}

module.exports = React;
147 changes: 33 additions & 114 deletions Libraries/ReactNative/ReactNative.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,128 +11,47 @@
*/
'use strict';

// Require ReactNativeDefaultInjection first for its side effects of setting up
// the JS environment
var ReactNativeDefaultInjection = require('ReactNativeDefaultInjection');
const ReactIsomorphic = require('ReactIsomorphic');
const ReactNativeImpl = require('ReactNativeImpl');
const warning = require('warning');

var ReactChildren = require('ReactChildren');
var ReactClass = require('ReactClass');
var ReactComponent = require('ReactComponent');
var ReactCurrentOwner = require('ReactCurrentOwner');
var ReactElement = require('ReactElement');
var ReactElementValidator = require('ReactElementValidator');
var ReactInstanceHandles = require('ReactInstanceHandles');
var ReactNativeMount = require('ReactNativeMount');
var ReactPropTypes = require('ReactPropTypes');
var ReactUpdates = require('ReactUpdates');
const ReactNative = { ...ReactNativeImpl };

var findNodeHandle = require('findNodeHandle');
var invariant = require('fbjs/lib/invariant');
var onlyChild = require('onlyChild');
var warning = require('fbjs/lib/warning');

ReactNativeDefaultInjection.inject();

var createElement = ReactElement.createElement;
var createFactory = ReactElement.createFactory;
var cloneElement = ReactElement.cloneElement;
const dedupe = {};

if (__DEV__) {
createElement = ReactElementValidator.createElement;
createFactory = ReactElementValidator.createFactory;
cloneElement = ReactElementValidator.cloneElement;
}

var resolveDefaultProps = function(element) {
// Could be optimized, but not currently in heavy use.
var defaultProps = element.type.defaultProps;
var props = element.props;
for (var propName in defaultProps) {
if (props[propName] === undefined) {
props[propName] = defaultProps[propName];
}
for (const key in ReactNativeImpl) {
Object.defineProperty(ReactNative, key, {
get: function() {
return ReactNativeImpl[key];
},
set: function(value) {
// Useful for hacky solutions like createExamplePage.
ReactNativeImpl[key] = value;
},
});
}
};
}

// Experimental optimized element creation
var augmentElement = function(element: ReactElement): ReactElement {
for (const key in ReactIsomorphic) {
ReactNative[key] = ReactIsomorphic[key];
if (__DEV__) {
invariant(
false,
'This optimized path should never be used in DEV mode because ' +
'it does not provide validation. Check your JSX transform.'
);
}
element._owner = ReactCurrentOwner.current;
if (element.type.defaultProps) {
resolveDefaultProps(element);
Object.defineProperty(ReactNative, key, {
get: function() {
warning(
dedupe[key],
'ReactNative.' + key + ' is deprecated. Use React.' + key +
' from the "react" package instead.'
);
dedupe[key] = true;
return ReactIsomorphic[key];
},
set: function(value) {
// Useful for hacky solutions like createExamplePage.
ReactIsomorphic[key] = value;
},
});
}
return element;
};

var render = function(
element: ReactElement,
mountInto: number,
callback?: ?(() => void)
): ?ReactComponent {
return ReactNativeMount.renderComponent(element, mountInto, callback);
};

var ReactNative = {
hasReactNativeInitialized: false,
Children: {
map: ReactChildren.map,
forEach: ReactChildren.forEach,
count: ReactChildren.count,
toArray: ReactChildren.toArray,
only: onlyChild
},
Component: ReactComponent,
PropTypes: ReactPropTypes,
createClass: ReactClass.createClass,
createElement: createElement,
createFactory: createFactory,
cloneElement: cloneElement,
_augmentElement: augmentElement,
findNodeHandle: findNodeHandle,
render: render,
unmountComponentAtNode: ReactNativeMount.unmountComponentAtNode,

/* eslint-disable camelcase */
unstable_batchedUpdates: ReactUpdates.batchedUpdates,
/* eslint-enable camelcase */

// Hook for JSX spread, don't use this for anything else.
__spread: Object.assign,

unmountComponentAtNodeAndRemoveContainer: ReactNativeMount.unmountComponentAtNodeAndRemoveContainer,
isValidClass: ReactElement.isValidFactory,
isValidElement: ReactElement.isValidElement,

// Deprecations (remove for 0.13)
renderComponent: function(
element: ReactElement,
mountInto: number,
callback?: ?(() => void)
): ?ReactComponent {
warning('Use React.render instead of React.renderComponent');
return ReactNative.render(element, mountInto, callback);
},
};

// Inject the runtime into a devtools global hook regardless of browser.
// Allows for debugging when the hook is injected on the page.
/* globals __REACT_DEVTOOLS_GLOBAL_HOOK__ */
if (
typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ !== 'undefined' &&
typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.inject === 'function') {
__REACT_DEVTOOLS_GLOBAL_HOOK__.inject({
CurrentOwner: ReactCurrentOwner,
InstanceHandles: ReactInstanceHandles,
Mount: ReactNativeMount,
Reconciler: require('ReactReconciler'),
TextComponent: require('ReactNativeTextComponent'),
});
}

module.exports = ReactNative;
64 changes: 64 additions & 0 deletions Libraries/ReactNative/ReactNativeImpl.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
/**
* Copyright (c) 2015-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*
* @providesModule ReactNativeImpl
* @flow
*/
'use strict';

// Require ReactNativeDefaultInjection first for its side effects of setting up
// the JS environment
var ReactNativeDefaultInjection = require('ReactNativeDefaultInjection');

var ReactCurrentOwner = require('ReactCurrentOwner');
var ReactElement = require('ReactElement');
var ReactInstanceHandles = require('ReactInstanceHandles');
var ReactNativeMount = require('ReactNativeMount');
var ReactUpdates = require('ReactUpdates');

var findNodeHandle = require('findNodeHandle');

ReactNativeDefaultInjection.inject();

var render = function(
element: ReactElement,
mountInto: number,
callback?: ?(() => void)
): ?ReactComponent {
return ReactNativeMount.renderComponent(element, mountInto, callback);
};

var ReactNative = {
hasReactNativeInitialized: false,
findNodeHandle: findNodeHandle,
render: render,
unmountComponentAtNode: ReactNativeMount.unmountComponentAtNode,

/* eslint-disable camelcase */
unstable_batchedUpdates: ReactUpdates.batchedUpdates,
/* eslint-enable camelcase */

unmountComponentAtNodeAndRemoveContainer: ReactNativeMount.unmountComponentAtNodeAndRemoveContainer,
};

// Inject the runtime into a devtools global hook regardless of browser.
// Allows for debugging when the hook is injected on the page.
/* globals __REACT_DEVTOOLS_GLOBAL_HOOK__ */
if (
typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ !== 'undefined' &&
typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.inject === 'function') {
__REACT_DEVTOOLS_GLOBAL_HOOK__.inject({
CurrentOwner: ReactCurrentOwner,
InstanceHandles: ReactInstanceHandles,
Mount: ReactNativeMount,
Reconciler: require('ReactReconciler'),
TextComponent: require('ReactNativeTextComponent'),
});
}

module.exports = ReactNative;
22 changes: 18 additions & 4 deletions Libraries/react-native/react-native.js
Original file line number Diff line number Diff line change
Expand Up @@ -115,12 +115,26 @@ var ReactNative = {
get createFragment() { return require('ReactFragment').create; },
get update() { return require('update'); },
},

// Note: this must be placed last to prevent eager
// evaluation of the getter-wrapped submodules above
...require('React'),
};

// Preserve getters with warnings on the internal ReactNative copy without
// invoking them.
var ReactNativeInternal = require('ReactNative');
function applyForwarding(key) {
if (__DEV__) {
Object.defineProperty(
ReactNative,
key,
Object.getOwnPropertyDescriptor(ReactNativeInternal, key)
);
return;
}
ReactNative[key] = ReactNativeInternal[key];
}
for (var key in ReactNativeInternal) {
applyForwarding(key);
}

if (__DEV__) {
Object.defineProperty(ReactNative.addons, 'Perf', {
enumerable: true,
Expand Down

0 comments on commit 2eafcd4

Please sign in to comment.