Sync React 16 from alpha 6 to 12
Reviewed By: spicyj Differential Revision: D4926070 fbshipit-source-id: c23c79ccd53eb594447d9b47fe3ac6e82499bd42
This commit is contained in:
Родитель
cc3d034460
Коммит
ef0bd5c71d
|
@ -11,7 +11,7 @@
|
|||
|
||||
'use strict';
|
||||
|
||||
var PooledClass = require('react/lib/PooledClass');
|
||||
var PooledClass = require('PooledClass');
|
||||
|
||||
var twoArgumentPooler = PooledClass.twoArgumentPooler;
|
||||
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
|
||||
'use strict';
|
||||
|
||||
var PooledClass = require('react/lib/PooledClass');
|
||||
var PooledClass = require('PooledClass');
|
||||
|
||||
var twoArgumentPooler = PooledClass.twoArgumentPooler;
|
||||
|
||||
|
|
|
@ -15,7 +15,6 @@ var ImageResizeMode = require('ImageResizeMode');
|
|||
var ImageStylePropTypes = require('ImageStylePropTypes');
|
||||
var NativeMethodsMixin = require('NativeMethodsMixin');
|
||||
var NativeModules = require('NativeModules');
|
||||
var PropTypes = require('react/lib/ReactPropTypes');
|
||||
var React = require('React');
|
||||
var PropTypes = require('prop-types');
|
||||
var ReactNativeViewAttributes = require('ReactNativeViewAttributes');
|
||||
|
|
|
@ -32,28 +32,32 @@ let _asyncCookie = 0;
|
|||
|
||||
const ReactSystraceDevtool = __DEV__ ? {
|
||||
onBeforeMountComponent(debugID) {
|
||||
const displayName = require('react/lib/ReactComponentTreeHook').getDisplayName(debugID);
|
||||
const ReactComponentTreeHook = require('ReactGlobalSharedState').ReactComponentTreeHook;
|
||||
const displayName = ReactComponentTreeHook.getDisplayName(debugID);
|
||||
Systrace.beginEvent(`ReactReconciler.mountComponent(${displayName})`);
|
||||
},
|
||||
onMountComponent(debugID) {
|
||||
Systrace.endEvent();
|
||||
},
|
||||
onBeforeUpdateComponent(debugID) {
|
||||
const displayName = require('react/lib/ReactComponentTreeHook').getDisplayName(debugID);
|
||||
const ReactComponentTreeHook = require('ReactGlobalSharedState').ReactComponentTreeHook;
|
||||
const displayName = ReactComponentTreeHook.getDisplayName(debugID);
|
||||
Systrace.beginEvent(`ReactReconciler.updateComponent(${displayName})`);
|
||||
},
|
||||
onUpdateComponent(debugID) {
|
||||
Systrace.endEvent();
|
||||
},
|
||||
onBeforeUnmountComponent(debugID) {
|
||||
const displayName = require('react/lib/ReactComponentTreeHook').getDisplayName(debugID);
|
||||
const ReactComponentTreeHook = require('ReactGlobalSharedState').ReactComponentTreeHook;
|
||||
const displayName = ReactComponentTreeHook.getDisplayName(debugID);
|
||||
Systrace.beginEvent(`ReactReconciler.unmountComponent(${displayName})`);
|
||||
},
|
||||
onUnmountComponent(debugID) {
|
||||
Systrace.endEvent();
|
||||
},
|
||||
onBeginLifeCycleTimer(debugID, timerType) {
|
||||
const displayName = require('react/lib/ReactComponentTreeHook').getDisplayName(debugID);
|
||||
const ReactComponentTreeHook = require('ReactGlobalSharedState').ReactComponentTreeHook;
|
||||
const displayName = ReactComponentTreeHook.getDisplayName(debugID);
|
||||
Systrace.beginEvent(`${displayName}.${timerType}()`);
|
||||
},
|
||||
onEndLifeCycleTimer(debugID, timerType) {
|
||||
|
|
|
@ -11,4 +11,4 @@
|
|||
|
||||
'use strict';
|
||||
|
||||
module.exports = '16.0.0-alpha.6';
|
||||
module.exports = '16.0.0-alpha.12';
|
||||
|
|
|
@ -99,7 +99,7 @@ var NativeMethodsMixin = {
|
|||
},
|
||||
|
||||
/**
|
||||
* Like [`measure()`](#measure), but measures the view relative to an ancestor,
|
||||
* Like [`measure()`](#measure), but measures the view relative an ancestor,
|
||||
* specified as `relativeToNativeNode`. This means that the returned x, y
|
||||
* are relative to the origin x, y of the ancestor view.
|
||||
*
|
||||
|
@ -176,7 +176,8 @@ function setNativePropsFiber(componentOrHandle: any, nativeProps: Object) {
|
|||
return;
|
||||
}
|
||||
|
||||
const viewConfig: ReactNativeBaseComponentViewConfig = maybeInstance.viewConfig;
|
||||
const viewConfig: ReactNativeBaseComponentViewConfig =
|
||||
maybeInstance.viewConfig;
|
||||
|
||||
if (__DEV__) {
|
||||
warnForStyleProps(nativeProps, viewConfig.validAttributes);
|
||||
|
|
|
@ -71,12 +71,14 @@ function throwOnStylesProp(component: any, props: any) {
|
|||
if (props.styles !== undefined) {
|
||||
var owner = component._owner || null;
|
||||
var name = component.constructor.displayName;
|
||||
var msg = '`styles` is not a supported property of `' +
|
||||
var msg =
|
||||
'`styles` is not a supported property of `' +
|
||||
name +
|
||||
'`, did ' +
|
||||
'you mean `style` (singular)?';
|
||||
if (owner && owner.constructor && owner.constructor.displayName) {
|
||||
msg += '\n\nCheck the `' +
|
||||
msg +=
|
||||
'\n\nCheck the `' +
|
||||
owner.constructor.displayName +
|
||||
'` parent ' +
|
||||
' component.';
|
||||
|
|
|
@ -377,7 +377,8 @@ function diffProperties(
|
|||
typeof attributeConfig.process === 'function'
|
||||
) {
|
||||
// case: CustomAttributeConfiguration
|
||||
var shouldUpdate = prevProp === undefined ||
|
||||
var shouldUpdate =
|
||||
prevProp === undefined ||
|
||||
(typeof attributeConfig.diff === 'function'
|
||||
? attributeConfig.diff(prevProp, nextProp)
|
||||
: defaultDiffer(prevProp, nextProp));
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
* @providesModule ReactNativeBaseComponent
|
||||
* @flow
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
var NativeMethodsMixin = require('NativeMethodsMixin');
|
||||
|
|
|
@ -23,9 +23,8 @@ var customDirectEventTypes = UIManager.customDirectEventTypes;
|
|||
var allTypesByEventName = {};
|
||||
|
||||
for (var bubblingTypeName in customBubblingEventTypes) {
|
||||
allTypesByEventName[bubblingTypeName] = customBubblingEventTypes[
|
||||
bubblingTypeName
|
||||
];
|
||||
allTypesByEventName[bubblingTypeName] =
|
||||
customBubblingEventTypes[bubblingTypeName];
|
||||
}
|
||||
|
||||
for (var directTypeName in customDirectEventTypes) {
|
||||
|
|
|
@ -23,6 +23,7 @@ const ReactNativeInjection = require('ReactNativeInjection');
|
|||
const ReactNativeTagHandles = require('ReactNativeTagHandles');
|
||||
const ReactNativeViewConfigRegistry = require('ReactNativeViewConfigRegistry');
|
||||
const ReactPortal = require('ReactPortal');
|
||||
const ReactVersion = require('ReactVersion');
|
||||
const UIManager = require('UIManager');
|
||||
|
||||
const deepFreezeAndThrowOnMutationInDev = require('deepFreezeAndThrowOnMutationInDev');
|
||||
|
@ -239,9 +240,9 @@ const NativeRenderer = ReactFiberReconciler({
|
|||
// Either way we need to pass a copy of the Array to prevent it from being frozen.
|
||||
const nativeTags = parentInstance._children.map(
|
||||
child =>
|
||||
typeof child === 'number'
|
||||
(typeof child === 'number'
|
||||
? child // Leaf node (eg text)
|
||||
: child._nativeTag,
|
||||
: child._nativeTag),
|
||||
);
|
||||
|
||||
UIManager.setChildren(
|
||||
|
@ -396,7 +397,8 @@ ReactGenericBatching.injection.injectFiberBatchedUpdates(
|
|||
const roots = new Map();
|
||||
|
||||
findNodeHandle.injection.injectFindNode((fiber: Fiber) =>
|
||||
NativeRenderer.findHostInstance(fiber));
|
||||
NativeRenderer.findHostInstance(fiber),
|
||||
);
|
||||
findNodeHandle.injection.injectFindRootNodeID(instance => instance);
|
||||
|
||||
// Intercept lifecycle errors and ensure they are shown with the correct stack
|
||||
|
@ -463,6 +465,9 @@ if (typeof injectInternals === 'function') {
|
|||
injectInternals({
|
||||
findFiberByHostInstance: ReactNativeComponentTree.getClosestInstanceFromNode,
|
||||
findHostInstanceByFiber: NativeRenderer.findHostInstance,
|
||||
// This is an enum because we may add more (e.g. profiler build)
|
||||
bundleType: __DEV__ ? 1 : 0,
|
||||
version: ReactVersion,
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -17,10 +17,7 @@ var ReactNativeAttributePayload = require('ReactNativeAttributePayload');
|
|||
var TextInputState = require('TextInputState');
|
||||
var UIManager = require('UIManager');
|
||||
|
||||
var {
|
||||
mountSafeCallback,
|
||||
warnForStyleProps,
|
||||
} = require('NativeMethodsMixinUtils');
|
||||
var {mountSafeCallback, warnForStyleProps} = require('NativeMethodsMixinUtils');
|
||||
|
||||
import type {
|
||||
MeasureInWindowOnSuccessCallback,
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
|
||||
'use strict';
|
||||
|
||||
var PropTypes;
|
||||
var RCTEventEmitter;
|
||||
var React;
|
||||
var ReactNative;
|
||||
|
@ -21,6 +22,7 @@ var createReactNativeComponentClass;
|
|||
beforeEach(() => {
|
||||
jest.resetModules();
|
||||
|
||||
PropTypes = require('prop-types');
|
||||
RCTEventEmitter = require('RCTEventEmitter');
|
||||
React = require('react');
|
||||
ReactNative = require('ReactNative');
|
||||
|
@ -56,6 +58,7 @@ it('handles events', () => {
|
|||
1,
|
||||
);
|
||||
|
||||
expect(UIManager.__dumpHierarchyForJestTestsOnly()).toMatchSnapshot();
|
||||
expect(UIManager.createView.mock.calls.length).toBe(2);
|
||||
|
||||
// Don't depend on the order of createView() calls.
|
||||
|
|
|
@ -69,7 +69,7 @@ describe('ReactNative', () => {
|
|||
var a;
|
||||
var b;
|
||||
var c = ReactNative.render(
|
||||
<View foo="foo" ref={v => a = v} />,
|
||||
<View foo="foo" ref={v => (a = v)} />,
|
||||
11,
|
||||
function() {
|
||||
b = this;
|
||||
|
@ -80,4 +80,32 @@ describe('ReactNative', () => {
|
|||
expect(a).toBe(b);
|
||||
expect(a).toBe(c);
|
||||
});
|
||||
|
||||
it('renders and reorders children', () => {
|
||||
var View = createReactNativeComponentClass({
|
||||
validAttributes: {title: true},
|
||||
uiViewClassName: 'View',
|
||||
});
|
||||
|
||||
class Component extends React.Component {
|
||||
render() {
|
||||
var chars = this.props.chars.split('');
|
||||
return (
|
||||
<View>
|
||||
{chars.map(text => <View key={text} title={text} />)}
|
||||
</View>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// Mini multi-child stress test: lots of reorders, some adds, some removes.
|
||||
var before = 'abcdefghijklmnopqrst';
|
||||
var after = 'mxhpgwfralkeoivcstzy';
|
||||
|
||||
ReactNative.render(<Component chars={before} />, 11);
|
||||
expect(UIManager.__dumpHierarchyForJestTestsOnly()).toMatchSnapshot();
|
||||
|
||||
ReactNative.render(<Component chars={after} />, 11);
|
||||
expect(UIManager.__dumpHierarchyForJestTestsOnly()).toMatchSnapshot();
|
||||
});
|
||||
});
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`handles events 1`] = `
|
||||
"<native root> {}
|
||||
View {\\"foo\\":\\"outer\\"}
|
||||
View {\\"foo\\":\\"inner\\"}"
|
||||
`;
|
|
@ -0,0 +1,51 @@
|
|||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`ReactNative renders and reorders children 1`] = `
|
||||
"<native root> {}
|
||||
View null
|
||||
View {\\"title\\":\\"a\\"}
|
||||
View {\\"title\\":\\"b\\"}
|
||||
View {\\"title\\":\\"c\\"}
|
||||
View {\\"title\\":\\"d\\"}
|
||||
View {\\"title\\":\\"e\\"}
|
||||
View {\\"title\\":\\"f\\"}
|
||||
View {\\"title\\":\\"g\\"}
|
||||
View {\\"title\\":\\"h\\"}
|
||||
View {\\"title\\":\\"i\\"}
|
||||
View {\\"title\\":\\"j\\"}
|
||||
View {\\"title\\":\\"k\\"}
|
||||
View {\\"title\\":\\"l\\"}
|
||||
View {\\"title\\":\\"m\\"}
|
||||
View {\\"title\\":\\"n\\"}
|
||||
View {\\"title\\":\\"o\\"}
|
||||
View {\\"title\\":\\"p\\"}
|
||||
View {\\"title\\":\\"q\\"}
|
||||
View {\\"title\\":\\"r\\"}
|
||||
View {\\"title\\":\\"s\\"}
|
||||
View {\\"title\\":\\"t\\"}"
|
||||
`;
|
||||
|
||||
exports[`ReactNative renders and reorders children 2`] = `
|
||||
"<native root> {}
|
||||
View null
|
||||
View {\\"title\\":\\"m\\"}
|
||||
View {\\"title\\":\\"x\\"}
|
||||
View {\\"title\\":\\"h\\"}
|
||||
View {\\"title\\":\\"p\\"}
|
||||
View {\\"title\\":\\"g\\"}
|
||||
View {\\"title\\":\\"w\\"}
|
||||
View {\\"title\\":\\"f\\"}
|
||||
View {\\"title\\":\\"r\\"}
|
||||
View {\\"title\\":\\"a\\"}
|
||||
View {\\"title\\":\\"l\\"}
|
||||
View {\\"title\\":\\"k\\"}
|
||||
View {\\"title\\":\\"e\\"}
|
||||
View {\\"title\\":\\"o\\"}
|
||||
View {\\"title\\":\\"i\\"}
|
||||
View {\\"title\\":\\"v\\"}
|
||||
View {\\"title\\":\\"c\\"}
|
||||
View {\\"title\\":\\"s\\"}
|
||||
View {\\"title\\":\\"t\\"}
|
||||
View {\\"title\\":\\"z\\"}
|
||||
View {\\"title\\":\\"y\\"}"
|
||||
`;
|
|
@ -12,8 +12,8 @@
|
|||
|
||||
'use strict';
|
||||
|
||||
var ReactCurrentOwner = require('react/lib/ReactCurrentOwner');
|
||||
var ReactInstanceMap = require('ReactInstanceMap');
|
||||
var {ReactCurrentOwner} = require('ReactGlobalSharedState');
|
||||
|
||||
var invariant = require('fbjs/lib/invariant');
|
||||
var warning = require('fbjs/lib/warning');
|
||||
|
|
|
@ -33,23 +33,22 @@ import type {Element} from 'React';
|
|||
* Returns a Promise.
|
||||
* @platform ios
|
||||
*/
|
||||
module.exports = async function takeSnapshot(
|
||||
view ?: 'window' | Element<any> | number,
|
||||
options ?: {
|
||||
width ?: number,
|
||||
height ?: number,
|
||||
format ?: 'png' | 'jpeg',
|
||||
quality ?: number,
|
||||
function takeSnapshot(
|
||||
view?: 'window' | Element<any> | number,
|
||||
options?: {
|
||||
width?: number,
|
||||
height?: number,
|
||||
format?: 'png' | 'jpeg',
|
||||
quality?: number,
|
||||
},
|
||||
) {
|
||||
if (
|
||||
typeof view !== 'number' &&
|
||||
view !== 'window'
|
||||
) {
|
||||
): Promise<any> {
|
||||
if (typeof view !== 'number' && view !== 'window') {
|
||||
view = ReactNative.findNodeHandle(view) || 'window';
|
||||
}
|
||||
|
||||
// Call the hidden '__takeSnapshot' method; the main one throws an error to
|
||||
// prevent accidental backwards-incompatible usage.
|
||||
return UIManager.__takeSnapshot(view, options);
|
||||
};
|
||||
}
|
||||
|
||||
module.exports = takeSnapshot;
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
import type { Fiber } from 'ReactFiber';
|
||||
import type { UpdateQueue } from 'ReactFiberUpdateQueue';
|
||||
|
||||
var ReactFiberInstrumentation = require('ReactFiberInstrumentation');
|
||||
var ReactFiberReconciler = require('ReactFiberReconciler');
|
||||
var ReactInstanceMap = require('ReactInstanceMap');
|
||||
var {
|
||||
|
@ -380,6 +381,11 @@ var ReactNoop = {
|
|||
}
|
||||
},
|
||||
|
||||
__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED: {
|
||||
// Private. Used only by fixtures/fiber-debugger.
|
||||
// (To be fair, it's the only place where `react-noop-renderer` package is used at all.)
|
||||
ReactFiberInstrumentation,
|
||||
},
|
||||
};
|
||||
|
||||
module.exports = ReactNoop;
|
||||
|
|
|
@ -0,0 +1,170 @@
|
|||
/**
|
||||
* Copyright 2013-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 ReactDOMFrameScheduling
|
||||
* @flow
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
// This a built-in polyfill for requestIdleCallback. It works by scheduling
|
||||
// a requestAnimationFrame, store the time for the start of the frame, then
|
||||
// schedule a postMessage which gets scheduled after paint. Within the
|
||||
// postMessage handler do as much work as possible until time + frame rate.
|
||||
// By separating the idle call into a separate event tick we ensure that
|
||||
// layout, paint and other browser work is counted against the available time.
|
||||
// The frame rate is dynamically adjusted.
|
||||
|
||||
import type {Deadline} from 'ReactFiberReconciler';
|
||||
|
||||
var invariant = require('fbjs/lib/invariant');
|
||||
var ExecutionEnvironment = require('fbjs/lib/ExecutionEnvironment');
|
||||
|
||||
// TODO: There's no way to cancel these, because Fiber doesn't atm.
|
||||
let rAF: (callback: (time: number) => void) => number;
|
||||
let rIC: (callback: (deadline: Deadline) => void) => number;
|
||||
|
||||
if (!ExecutionEnvironment.canUseDOM) {
|
||||
rAF = function(frameCallback: (time: number) => void): number {
|
||||
setTimeout(frameCallback, 16);
|
||||
return 0;
|
||||
};
|
||||
|
||||
rIC = function(frameCallback: (deadline: Deadline) => void): number {
|
||||
setTimeout(() => {
|
||||
frameCallback({
|
||||
timeRemaining() {
|
||||
return Infinity;
|
||||
},
|
||||
});
|
||||
});
|
||||
return 0;
|
||||
};
|
||||
} else if (typeof requestAnimationFrame !== 'function') {
|
||||
invariant(
|
||||
false,
|
||||
'React depends on requestAnimationFrame. Make sure that you load a ' +
|
||||
'polyfill in older browsers.',
|
||||
);
|
||||
} else if (typeof requestIdleCallback !== 'function') {
|
||||
// Wrap requestAnimationFrame and polyfill requestIdleCallback.
|
||||
|
||||
var scheduledRAFCallback = null;
|
||||
var scheduledRICCallback = null;
|
||||
|
||||
var isIdleScheduled = false;
|
||||
var isAnimationFrameScheduled = false;
|
||||
|
||||
var frameDeadline = 0;
|
||||
// We start out assuming that we run at 30fps but then the heuristic tracking
|
||||
// will adjust this value to a faster fps if we get more frequent animation
|
||||
// frames.
|
||||
var previousFrameTime = 33;
|
||||
var activeFrameTime = 33;
|
||||
|
||||
var frameDeadlineObject = {
|
||||
timeRemaining: typeof performance === 'object' &&
|
||||
typeof performance.now === 'function'
|
||||
? function() {
|
||||
// We assume that if we have a performance timer that the rAF callback
|
||||
// gets a performance timer value. Not sure if this is always true.
|
||||
return frameDeadline - performance.now();
|
||||
}
|
||||
: function() {
|
||||
// As a fallback we use Date.now.
|
||||
return frameDeadline - Date.now();
|
||||
},
|
||||
};
|
||||
|
||||
// We use the postMessage trick to defer idle work until after the repaint.
|
||||
var messageKey = '__reactIdleCallback$' + Math.random().toString(36).slice(2);
|
||||
var idleTick = function(event) {
|
||||
if (event.source !== window || event.data !== messageKey) {
|
||||
return;
|
||||
}
|
||||
isIdleScheduled = false;
|
||||
var callback = scheduledRICCallback;
|
||||
scheduledRICCallback = null;
|
||||
if (callback) {
|
||||
callback(frameDeadlineObject);
|
||||
}
|
||||
};
|
||||
// Assumes that we have addEventListener in this environment. Might need
|
||||
// something better for old IE.
|
||||
window.addEventListener('message', idleTick, false);
|
||||
|
||||
var animationTick = function(rafTime) {
|
||||
isAnimationFrameScheduled = false;
|
||||
var nextFrameTime = rafTime - frameDeadline + activeFrameTime;
|
||||
if (
|
||||
nextFrameTime < activeFrameTime &&
|
||||
previousFrameTime < activeFrameTime
|
||||
) {
|
||||
if (nextFrameTime < 8) {
|
||||
// Defensive coding. We don't support higher frame rates than 120hz.
|
||||
// If we get lower than that, it is probably a bug.
|
||||
nextFrameTime = 8;
|
||||
}
|
||||
// If one frame goes long, then the next one can be short to catch up.
|
||||
// If two frames are short in a row, then that's an indication that we
|
||||
// actually have a higher frame rate than what we're currently optimizing.
|
||||
// We adjust our heuristic dynamically accordingly. For example, if we're
|
||||
// running on 120hz display or 90hz VR display.
|
||||
// Take the max of the two in case one of them was an anomaly due to
|
||||
// missed frame deadlines.
|
||||
activeFrameTime = nextFrameTime < previousFrameTime
|
||||
? previousFrameTime
|
||||
: nextFrameTime;
|
||||
} else {
|
||||
previousFrameTime = nextFrameTime;
|
||||
}
|
||||
frameDeadline = rafTime + activeFrameTime;
|
||||
if (!isIdleScheduled) {
|
||||
isIdleScheduled = true;
|
||||
window.postMessage(messageKey, '*');
|
||||
}
|
||||
var callback = scheduledRAFCallback;
|
||||
scheduledRAFCallback = null;
|
||||
if (callback) {
|
||||
callback(rafTime);
|
||||
}
|
||||
};
|
||||
|
||||
rAF = function(callback: (time: number) => void): number {
|
||||
// This assumes that we only schedule one callback at a time because that's
|
||||
// how Fiber uses it.
|
||||
scheduledRAFCallback = callback;
|
||||
if (!isAnimationFrameScheduled) {
|
||||
// If rIC didn't already schedule one, we need to schedule a frame.
|
||||
isAnimationFrameScheduled = true;
|
||||
requestAnimationFrame(animationTick);
|
||||
}
|
||||
return 0;
|
||||
};
|
||||
|
||||
rIC = function(callback: (deadline: Deadline) => void): number {
|
||||
// This assumes that we only schedule one callback at a time because that's
|
||||
// how Fiber uses it.
|
||||
scheduledRICCallback = callback;
|
||||
if (!isAnimationFrameScheduled) {
|
||||
// If rAF didn't already schedule one, we need to schedule a frame.
|
||||
// TODO: If this rAF doesn't materialize because the browser throttles, we
|
||||
// might want to still have setTimeout trigger rIC as a backup to ensure
|
||||
// that we keep performing work.
|
||||
isAnimationFrameScheduled = true;
|
||||
requestAnimationFrame(animationTick);
|
||||
}
|
||||
return 0;
|
||||
};
|
||||
} else {
|
||||
rAF = requestAnimationFrame;
|
||||
rIC = requestIdleCallback;
|
||||
}
|
||||
|
||||
exports.rAF = rAF;
|
||||
exports.rIC = rIC;
|
|
@ -14,8 +14,8 @@
|
|||
|
||||
var ReactInvalidSetStateWarningHook = require('ReactInvalidSetStateWarningHook');
|
||||
var ReactHostOperationHistoryHook = require('ReactHostOperationHistoryHook');
|
||||
var ReactComponentTreeHook = require('react/lib/ReactComponentTreeHook');
|
||||
var ExecutionEnvironment = require('fbjs/lib/ExecutionEnvironment');
|
||||
var {ReactComponentTreeHook} = require('ReactGlobalSharedState');
|
||||
|
||||
var performanceNow = require('fbjs/lib/performanceNow');
|
||||
var warning = require('fbjs/lib/warning');
|
||||
|
@ -113,25 +113,22 @@ if (__DEV__) {
|
|||
};
|
||||
|
||||
const getTreeSnapshot = function(registeredIDs) {
|
||||
return registeredIDs.reduce(
|
||||
(tree, id) => {
|
||||
var ownerID = ReactComponentTreeHook.getOwnerID(id);
|
||||
var parentID = ReactComponentTreeHook.getParentID(id);
|
||||
tree[id] = {
|
||||
displayName: ReactComponentTreeHook.getDisplayName(id),
|
||||
text: ReactComponentTreeHook.getText(id),
|
||||
updateCount: ReactComponentTreeHook.getUpdateCount(id),
|
||||
childIDs: ReactComponentTreeHook.getChildIDs(id),
|
||||
// Text nodes don't have owners but this is close enough.
|
||||
ownerID: ownerID ||
|
||||
(parentID && ReactComponentTreeHook.getOwnerID(parentID)) ||
|
||||
0,
|
||||
parentID,
|
||||
};
|
||||
return tree;
|
||||
},
|
||||
{},
|
||||
);
|
||||
return registeredIDs.reduce((tree, id) => {
|
||||
var ownerID = ReactComponentTreeHook.getOwnerID(id);
|
||||
var parentID = ReactComponentTreeHook.getParentID(id);
|
||||
tree[id] = {
|
||||
displayName: ReactComponentTreeHook.getDisplayName(id),
|
||||
text: ReactComponentTreeHook.getText(id),
|
||||
updateCount: ReactComponentTreeHook.getUpdateCount(id),
|
||||
childIDs: ReactComponentTreeHook.getChildIDs(id),
|
||||
// Text nodes don't have owners but this is close enough.
|
||||
ownerID: ownerID ||
|
||||
(parentID && ReactComponentTreeHook.getOwnerID(parentID)) ||
|
||||
0,
|
||||
parentID,
|
||||
};
|
||||
return tree;
|
||||
}, {});
|
||||
};
|
||||
|
||||
const resetMeasurements = function() {
|
||||
|
@ -252,7 +249,8 @@ if (__DEV__) {
|
|||
};
|
||||
|
||||
var lastMarkTimeStamp = 0;
|
||||
var canUsePerformanceMeasure: boolean = typeof performance !== 'undefined' &&
|
||||
var canUsePerformanceMeasure: boolean =
|
||||
typeof performance !== 'undefined' &&
|
||||
typeof performance.mark === 'function' &&
|
||||
typeof performance.clearMarks === 'function' &&
|
||||
typeof performance.measure === 'function' &&
|
||||
|
@ -289,8 +287,8 @@ if (__DEV__) {
|
|||
}
|
||||
|
||||
var markName = `${debugID}::${markType}`;
|
||||
var displayName = ReactComponentTreeHook.getDisplayName(debugID) ||
|
||||
'Unknown';
|
||||
var displayName =
|
||||
ReactComponentTreeHook.getDisplayName(debugID) || 'Unknown';
|
||||
|
||||
// Chrome has an issue of dropping markers recorded too fast:
|
||||
// https://bugs.chromium.org/p/chromium/issues/detail?id=640652
|
||||
|
@ -305,7 +303,9 @@ if (__DEV__) {
|
|||
}
|
||||
|
||||
performance.clearMarks(markName);
|
||||
performance.clearMeasures(measurementName);
|
||||
if (measurementName) {
|
||||
performance.clearMeasures(measurementName);
|
||||
}
|
||||
};
|
||||
|
||||
ReactDebugTool = {
|
||||
|
|
|
@ -0,0 +1,28 @@
|
|||
/**
|
||||
* Copyright 2013-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 ReactGlobalSharedState
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
var ReactInternals = require('react')
|
||||
.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED;
|
||||
|
||||
var ReactGlobalSharedState = {
|
||||
ReactCurrentOwner: ReactInternals.ReactCurrentOwner,
|
||||
};
|
||||
|
||||
if (__DEV__) {
|
||||
Object.assign(ReactGlobalSharedState, {
|
||||
ReactComponentTreeHook: ReactInternals.ReactComponentTreeHook,
|
||||
ReactDebugCurrentFrame: ReactInternals.ReactDebugCurrentFrame,
|
||||
});
|
||||
}
|
||||
|
||||
module.exports = ReactGlobalSharedState;
|
|
@ -71,13 +71,13 @@ function getExclusive(flushHistory = getLastMeasurements()) {
|
|||
var stats = aggregatedStats[key];
|
||||
if (!stats) {
|
||||
affectedIDs[key] = {};
|
||||
stats = (aggregatedStats[key] = {
|
||||
stats = aggregatedStats[key] = {
|
||||
key,
|
||||
instanceCount: 0,
|
||||
counts: {},
|
||||
durations: {},
|
||||
totalDuration: 0,
|
||||
});
|
||||
};
|
||||
}
|
||||
if (!stats.durations[timerType]) {
|
||||
stats.durations[timerType] = 0;
|
||||
|
@ -125,12 +125,12 @@ function getInclusive(flushHistory = getLastMeasurements()) {
|
|||
var stats = aggregatedStats[key];
|
||||
if (!stats) {
|
||||
affectedIDs[key] = {};
|
||||
stats = (aggregatedStats[key] = {
|
||||
stats = aggregatedStats[key] = {
|
||||
key,
|
||||
instanceCount: 0,
|
||||
inclusiveRenderDuration: 0,
|
||||
renderCount: 0,
|
||||
});
|
||||
};
|
||||
}
|
||||
affectedIDs[key][instanceID] = true;
|
||||
applyUpdate(stats);
|
||||
|
@ -196,12 +196,12 @@ function getWasted(flushHistory = getLastMeasurements()) {
|
|||
var stats = aggregatedStats[key];
|
||||
if (!stats) {
|
||||
affectedIDs[key] = {};
|
||||
stats = (aggregatedStats[key] = {
|
||||
stats = aggregatedStats[key] = {
|
||||
key,
|
||||
instanceCount: 0,
|
||||
inclusiveRenderDuration: 0,
|
||||
renderCount: 0,
|
||||
});
|
||||
};
|
||||
}
|
||||
affectedIDs[key][instanceID] = true;
|
||||
applyUpdate(stats);
|
||||
|
@ -255,7 +255,8 @@ function getWasted(flushHistory = getLastMeasurements()) {
|
|||
while (nextParentID) {
|
||||
// Any parents rendered during this batch are considered wasted
|
||||
// unless we previously marked them as dirty.
|
||||
var isWasted = renderedCompositeIDs[nextParentID] &&
|
||||
var isWasted =
|
||||
renderedCompositeIDs[nextParentID] &&
|
||||
!isDefinitelyNotWastedByID[nextParentID];
|
||||
if (isWasted) {
|
||||
updateAggregatedStats(treeSnapshot, nextParentID, stats => {
|
||||
|
|
|
@ -0,0 +1,55 @@
|
|||
/**
|
||||
* Copyright 2016-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.
|
||||
*
|
||||
* @emails react-core
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
const ReactDOMFeatureFlags = require('ReactDOMFeatureFlags');
|
||||
const describeFiber = ReactDOMFeatureFlags.useFiber ? describe : xdescribe;
|
||||
|
||||
describeFiber('ReactDOMFrameScheduling', () => {
|
||||
it('throws when requestAnimationFrame is not polyfilled in the browser', () => {
|
||||
const previousRAF = global.requestAnimationFrame;
|
||||
try {
|
||||
global.requestAnimationFrame = undefined;
|
||||
jest.resetModules();
|
||||
expect(() => {
|
||||
require('ReactDOM');
|
||||
}).toThrow(
|
||||
'React depends on requestAnimationFrame. Make sure that you load a ' +
|
||||
'polyfill in older browsers.',
|
||||
);
|
||||
} finally {
|
||||
global.requestAnimationFrame = previousRAF;
|
||||
}
|
||||
});
|
||||
|
||||
// We're just testing importing, not using it.
|
||||
// It is important because even isomorphic components may import it.
|
||||
it('can import findDOMNode in Node environment', () => {
|
||||
const previousRAF = global.requestAnimationFrame;
|
||||
const previousRIC = global.requestIdleCallback;
|
||||
const prevWindow = global.window;
|
||||
try {
|
||||
global.requestAnimationFrame = undefined;
|
||||
global.requestIdleCallback = undefined;
|
||||
// Simulate the Node environment:
|
||||
delete global.window;
|
||||
jest.resetModules();
|
||||
expect(() => {
|
||||
require('ReactDOM');
|
||||
}).not.toThrow();
|
||||
} finally {
|
||||
global.requestAnimationFrame = previousRAF;
|
||||
global.requestIdleCallback = previousRIC;
|
||||
global.window = prevWindow;
|
||||
}
|
||||
});
|
||||
});
|
|
@ -20,13 +20,8 @@ import type {ReactInstance} from 'ReactInstanceType';
|
|||
import type {PriorityLevel} from 'ReactPriorityLevel';
|
||||
|
||||
var REACT_ELEMENT_TYPE = require('ReactElementSymbol');
|
||||
var {
|
||||
REACT_COROUTINE_TYPE,
|
||||
REACT_YIELD_TYPE,
|
||||
} = require('ReactCoroutine');
|
||||
var {
|
||||
REACT_PORTAL_TYPE,
|
||||
} = require('ReactPortal');
|
||||
var {REACT_COROUTINE_TYPE, REACT_YIELD_TYPE} = require('ReactCoroutine');
|
||||
var {REACT_PORTAL_TYPE} = require('ReactPortal');
|
||||
|
||||
var ReactFiber = require('ReactFiber');
|
||||
var ReactTypeOfSideEffect = require('ReactTypeOfSideEffect');
|
||||
|
@ -36,13 +31,49 @@ var emptyObject = require('fbjs/lib/emptyObject');
|
|||
var getIteratorFn = require('getIteratorFn');
|
||||
var invariant = require('fbjs/lib/invariant');
|
||||
var ReactFeatureFlags = require('ReactFeatureFlags');
|
||||
var ReactCurrentOwner = require('react/lib/ReactCurrentOwner');
|
||||
|
||||
if (__DEV__) {
|
||||
var {getCurrentFiberStackAddendum} = require('ReactDebugCurrentFiber');
|
||||
var getComponentName = require('getComponentName');
|
||||
var warning = require('fbjs/lib/warning');
|
||||
var didWarnAboutMaps = false;
|
||||
/**
|
||||
* Warn if there's no key explicitly set on dynamic arrays of children or
|
||||
* object keys are not valid. This allows us to keep track of children between
|
||||
* updates.
|
||||
*/
|
||||
var ownerHasKeyUseWarning = {};
|
||||
|
||||
var warnForMissingKey = (child: mixed) => {
|
||||
if (child === null || typeof child !== 'object') {
|
||||
return;
|
||||
}
|
||||
if (!child._store || child._store.validated || child.key != null) {
|
||||
return;
|
||||
}
|
||||
invariant(
|
||||
typeof child._store === 'object',
|
||||
'React Component in warnForMissingKey should have a _store',
|
||||
);
|
||||
child._store.validated = true;
|
||||
|
||||
var currentComponentErrorInfo =
|
||||
'Each child in an array or iterator should have a unique ' +
|
||||
'"key" prop. See https://fb.me/react-warning-keys for ' +
|
||||
'more information.' +
|
||||
(getCurrentFiberStackAddendum(child) || '');
|
||||
if (ownerHasKeyUseWarning[currentComponentErrorInfo]) {
|
||||
return;
|
||||
}
|
||||
ownerHasKeyUseWarning[currentComponentErrorInfo] = true;
|
||||
|
||||
warning(
|
||||
false,
|
||||
'Each child in an array or iterator should have a unique ' +
|
||||
'"key" prop. See https://fb.me/react-warning-keys for ' +
|
||||
'more information.%s',
|
||||
getCurrentFiberStackAddendum(child),
|
||||
);
|
||||
};
|
||||
}
|
||||
|
||||
const {
|
||||
|
@ -67,11 +98,7 @@ const {
|
|||
Fragment,
|
||||
} = ReactTypeOfWork;
|
||||
|
||||
const {
|
||||
NoEffect,
|
||||
Placement,
|
||||
Deletion,
|
||||
} = ReactTypeOfSideEffect;
|
||||
const {NoEffect, Placement, Deletion} = ReactTypeOfSideEffect;
|
||||
|
||||
function coerceRef(current: Fiber | null, element: ReactElement) {
|
||||
let mixedRef = element.ref;
|
||||
|
@ -126,15 +153,10 @@ function throwOnInvalidObjectType(returnFiber: Fiber, newChild: Object) {
|
|||
if (returnFiber.type !== 'textarea') {
|
||||
let addendum = '';
|
||||
if (__DEV__) {
|
||||
addendum = ' If you meant to render a collection of children, use an array ' +
|
||||
'instead.';
|
||||
const owner = ReactCurrentOwner.owner || returnFiber._debugOwner;
|
||||
if (owner && typeof owner.tag === 'number') {
|
||||
const name = getComponentName((owner: any));
|
||||
if (name) {
|
||||
addendum += '\n\nCheck the render method of `' + name + '`.';
|
||||
}
|
||||
}
|
||||
addendum =
|
||||
' If you meant to render a collection of children, use an array ' +
|
||||
'instead.' +
|
||||
(getCurrentFiberStackAddendum() || '');
|
||||
}
|
||||
invariant(
|
||||
false,
|
||||
|
@ -172,7 +194,7 @@ function ChildReconciler(shouldClone, shouldTrackSideEffects) {
|
|||
last.nextEffect = childToDelete;
|
||||
returnFiber.progressedLastDeletion = childToDelete;
|
||||
} else {
|
||||
returnFiber.progressedFirstDeletion = (returnFiber.progressedLastDeletion = childToDelete);
|
||||
returnFiber.progressedFirstDeletion = returnFiber.progressedLastDeletion = childToDelete;
|
||||
}
|
||||
childToDelete.nextEffect = null;
|
||||
childToDelete.effectTag = Deletion;
|
||||
|
@ -283,7 +305,11 @@ function ChildReconciler(shouldClone, shouldTrackSideEffects) {
|
|||
) {
|
||||
if (current === null || current.tag !== HostText) {
|
||||
// Insert
|
||||
const created = createFiberFromText(textContent, priority);
|
||||
const created = createFiberFromText(
|
||||
textContent,
|
||||
returnFiber.internalContextTag,
|
||||
priority,
|
||||
);
|
||||
created.return = returnFiber;
|
||||
return created;
|
||||
} else {
|
||||
|
@ -303,7 +329,11 @@ function ChildReconciler(shouldClone, shouldTrackSideEffects) {
|
|||
): Fiber {
|
||||
if (current === null || current.type !== element.type) {
|
||||
// Insert
|
||||
const created = createFiberFromElement(element, priority);
|
||||
const created = createFiberFromElement(
|
||||
element,
|
||||
returnFiber.internalContextTag,
|
||||
priority,
|
||||
);
|
||||
created.ref = coerceRef(current, element);
|
||||
created.return = returnFiber;
|
||||
return created;
|
||||
|
@ -330,7 +360,11 @@ function ChildReconciler(shouldClone, shouldTrackSideEffects) {
|
|||
// TODO: Should this also compare handler to determine whether to reuse?
|
||||
if (current === null || current.tag !== CoroutineComponent) {
|
||||
// Insert
|
||||
const created = createFiberFromCoroutine(coroutine, priority);
|
||||
const created = createFiberFromCoroutine(
|
||||
coroutine,
|
||||
returnFiber.internalContextTag,
|
||||
priority,
|
||||
);
|
||||
created.return = returnFiber;
|
||||
return created;
|
||||
} else {
|
||||
|
@ -350,7 +384,11 @@ function ChildReconciler(shouldClone, shouldTrackSideEffects) {
|
|||
): Fiber {
|
||||
if (current === null || current.tag !== YieldComponent) {
|
||||
// Insert
|
||||
const created = createFiberFromYield(yieldNode, priority);
|
||||
const created = createFiberFromYield(
|
||||
yieldNode,
|
||||
returnFiber.internalContextTag,
|
||||
priority,
|
||||
);
|
||||
created.type = yieldNode.value;
|
||||
created.return = returnFiber;
|
||||
return created;
|
||||
|
@ -376,7 +414,11 @@ function ChildReconciler(shouldClone, shouldTrackSideEffects) {
|
|||
current.stateNode.implementation !== portal.implementation
|
||||
) {
|
||||
// Insert
|
||||
const created = createFiberFromPortal(portal, priority);
|
||||
const created = createFiberFromPortal(
|
||||
portal,
|
||||
returnFiber.internalContextTag,
|
||||
priority,
|
||||
);
|
||||
created.return = returnFiber;
|
||||
return created;
|
||||
} else {
|
||||
|
@ -396,7 +438,11 @@ function ChildReconciler(shouldClone, shouldTrackSideEffects) {
|
|||
): Fiber {
|
||||
if (current === null || current.tag !== Fragment) {
|
||||
// Insert
|
||||
const created = createFiberFromFragment(fragment, priority);
|
||||
const created = createFiberFromFragment(
|
||||
fragment,
|
||||
returnFiber.internalContextTag,
|
||||
priority,
|
||||
);
|
||||
created.return = returnFiber;
|
||||
return created;
|
||||
} else {
|
||||
|
@ -417,7 +463,11 @@ function ChildReconciler(shouldClone, shouldTrackSideEffects) {
|
|||
// Text nodes doesn't have keys. If the previous node is implicitly keyed
|
||||
// we can continue to replace it without aborting even if it is not a text
|
||||
// node.
|
||||
const created = createFiberFromText('' + newChild, priority);
|
||||
const created = createFiberFromText(
|
||||
'' + newChild,
|
||||
returnFiber.internalContextTag,
|
||||
priority,
|
||||
);
|
||||
created.return = returnFiber;
|
||||
return created;
|
||||
}
|
||||
|
@ -425,34 +475,54 @@ function ChildReconciler(shouldClone, shouldTrackSideEffects) {
|
|||
if (typeof newChild === 'object' && newChild !== null) {
|
||||
switch (newChild.$$typeof) {
|
||||
case REACT_ELEMENT_TYPE: {
|
||||
const created = createFiberFromElement(newChild, priority);
|
||||
const created = createFiberFromElement(
|
||||
newChild,
|
||||
returnFiber.internalContextTag,
|
||||
priority,
|
||||
);
|
||||
created.ref = coerceRef(null, newChild);
|
||||
created.return = returnFiber;
|
||||
return created;
|
||||
}
|
||||
|
||||
case REACT_COROUTINE_TYPE: {
|
||||
const created = createFiberFromCoroutine(newChild, priority);
|
||||
const created = createFiberFromCoroutine(
|
||||
newChild,
|
||||
returnFiber.internalContextTag,
|
||||
priority,
|
||||
);
|
||||
created.return = returnFiber;
|
||||
return created;
|
||||
}
|
||||
|
||||
case REACT_YIELD_TYPE: {
|
||||
const created = createFiberFromYield(newChild, priority);
|
||||
const created = createFiberFromYield(
|
||||
newChild,
|
||||
returnFiber.internalContextTag,
|
||||
priority,
|
||||
);
|
||||
created.type = newChild.value;
|
||||
created.return = returnFiber;
|
||||
return created;
|
||||
}
|
||||
|
||||
case REACT_PORTAL_TYPE: {
|
||||
const created = createFiberFromPortal(newChild, priority);
|
||||
const created = createFiberFromPortal(
|
||||
newChild,
|
||||
returnFiber.internalContextTag,
|
||||
priority,
|
||||
);
|
||||
created.return = returnFiber;
|
||||
return created;
|
||||
}
|
||||
}
|
||||
|
||||
if (isArray(newChild) || getIteratorFn(newChild)) {
|
||||
const created = createFiberFromFragment(newChild, priority);
|
||||
const created = createFiberFromFragment(
|
||||
newChild,
|
||||
returnFiber.internalContextTag,
|
||||
priority,
|
||||
);
|
||||
created.return = returnFiber;
|
||||
return created;
|
||||
}
|
||||
|
@ -553,16 +623,18 @@ function ChildReconciler(shouldClone, shouldTrackSideEffects) {
|
|||
if (typeof newChild === 'object' && newChild !== null) {
|
||||
switch (newChild.$$typeof) {
|
||||
case REACT_ELEMENT_TYPE: {
|
||||
const matchedFiber = existingChildren.get(
|
||||
newChild.key === null ? newIdx : newChild.key,
|
||||
) || null;
|
||||
const matchedFiber =
|
||||
existingChildren.get(
|
||||
newChild.key === null ? newIdx : newChild.key,
|
||||
) || null;
|
||||
return updateElement(returnFiber, matchedFiber, newChild, priority);
|
||||
}
|
||||
|
||||
case REACT_COROUTINE_TYPE: {
|
||||
const matchedFiber = existingChildren.get(
|
||||
newChild.key === null ? newIdx : newChild.key,
|
||||
) || null;
|
||||
const matchedFiber =
|
||||
existingChildren.get(
|
||||
newChild.key === null ? newIdx : newChild.key,
|
||||
) || null;
|
||||
return updateCoroutine(returnFiber, matchedFiber, newChild, priority);
|
||||
}
|
||||
|
||||
|
@ -574,9 +646,10 @@ function ChildReconciler(shouldClone, shouldTrackSideEffects) {
|
|||
}
|
||||
|
||||
case REACT_PORTAL_TYPE: {
|
||||
const matchedFiber = existingChildren.get(
|
||||
newChild.key === null ? newIdx : newChild.key,
|
||||
) || null;
|
||||
const matchedFiber =
|
||||
existingChildren.get(
|
||||
newChild.key === null ? newIdx : newChild.key,
|
||||
) || null;
|
||||
return updatePortal(returnFiber, matchedFiber, newChild, priority);
|
||||
}
|
||||
}
|
||||
|
@ -592,7 +665,10 @@ function ChildReconciler(shouldClone, shouldTrackSideEffects) {
|
|||
return null;
|
||||
}
|
||||
|
||||
function warnOnDuplicateKey(
|
||||
/**
|
||||
* Warns if there is a duplicate or missing key
|
||||
*/
|
||||
function warnOnInvalidKey(
|
||||
child: mixed,
|
||||
knownKeys: Set<string> | null,
|
||||
): Set<string> | null {
|
||||
|
@ -604,6 +680,7 @@ function ChildReconciler(shouldClone, shouldTrackSideEffects) {
|
|||
case REACT_ELEMENT_TYPE:
|
||||
case REACT_COROUTINE_TYPE:
|
||||
case REACT_PORTAL_TYPE:
|
||||
warnForMissingKey(child);
|
||||
const key = child.key;
|
||||
if (typeof key !== 'string') {
|
||||
break;
|
||||
|
@ -663,7 +740,7 @@ function ChildReconciler(shouldClone, shouldTrackSideEffects) {
|
|||
let knownKeys = null;
|
||||
for (let i = 0; i < newChildren.length; i++) {
|
||||
const child = newChildren[i];
|
||||
knownKeys = warnOnDuplicateKey(child, knownKeys);
|
||||
knownKeys = warnOnInvalidKey(child, knownKeys);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -813,22 +890,12 @@ function ChildReconciler(shouldClone, shouldTrackSideEffects) {
|
|||
if (typeof newChildrenIterable.entries === 'function') {
|
||||
const possibleMap = (newChildrenIterable: any);
|
||||
if (possibleMap.entries === iteratorFn) {
|
||||
let mapsAsChildrenAddendum = '';
|
||||
const owner = ReactCurrentOwner.owner || returnFiber._debugOwner;
|
||||
if (owner && typeof owner.tag === 'number') {
|
||||
const mapsAsChildrenOwnerName = getComponentName((owner: any));
|
||||
if (mapsAsChildrenOwnerName) {
|
||||
mapsAsChildrenAddendum = '\n\nCheck the render method of `' +
|
||||
mapsAsChildrenOwnerName +
|
||||
'`.';
|
||||
}
|
||||
}
|
||||
warning(
|
||||
didWarnAboutMaps,
|
||||
'Using Maps as children is unsupported and will likely yield ' +
|
||||
'unexpected results. Convert it to a sequence/iterable of keyed ' +
|
||||
'ReactElements instead.%s',
|
||||
mapsAsChildrenAddendum,
|
||||
getCurrentFiberStackAddendum(),
|
||||
);
|
||||
didWarnAboutMaps = true;
|
||||
}
|
||||
|
@ -842,7 +909,7 @@ function ChildReconciler(shouldClone, shouldTrackSideEffects) {
|
|||
let step = newChildren.next();
|
||||
for (; !step.done; step = newChildren.next()) {
|
||||
const child = step.value;
|
||||
knownKeys = warnOnDuplicateKey(child, knownKeys);
|
||||
knownKeys = warnOnInvalidKey(child, knownKeys);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -992,7 +1059,11 @@ function ChildReconciler(shouldClone, shouldTrackSideEffects) {
|
|||
// The existing first child is not a text node so we need to create one
|
||||
// and delete the existing ones.
|
||||
deleteRemainingChildren(returnFiber, currentFirstChild);
|
||||
const created = createFiberFromText(textContent, priority);
|
||||
const created = createFiberFromText(
|
||||
textContent,
|
||||
returnFiber.internalContextTag,
|
||||
priority,
|
||||
);
|
||||
created.return = returnFiber;
|
||||
return created;
|
||||
}
|
||||
|
@ -1030,7 +1101,11 @@ function ChildReconciler(shouldClone, shouldTrackSideEffects) {
|
|||
child = child.sibling;
|
||||
}
|
||||
|
||||
const created = createFiberFromElement(element, priority);
|
||||
const created = createFiberFromElement(
|
||||
element,
|
||||
returnFiber.internalContextTag,
|
||||
priority,
|
||||
);
|
||||
created.ref = coerceRef(currentFirstChild, element);
|
||||
created.return = returnFiber;
|
||||
return created;
|
||||
|
@ -1064,7 +1139,11 @@ function ChildReconciler(shouldClone, shouldTrackSideEffects) {
|
|||
child = child.sibling;
|
||||
}
|
||||
|
||||
const created = createFiberFromCoroutine(coroutine, priority);
|
||||
const created = createFiberFromCoroutine(
|
||||
coroutine,
|
||||
returnFiber.internalContextTag,
|
||||
priority,
|
||||
);
|
||||
created.return = returnFiber;
|
||||
return created;
|
||||
}
|
||||
|
@ -1089,7 +1168,11 @@ function ChildReconciler(shouldClone, shouldTrackSideEffects) {
|
|||
}
|
||||
}
|
||||
|
||||
const created = createFiberFromYield(yieldNode, priority);
|
||||
const created = createFiberFromYield(
|
||||
yieldNode,
|
||||
returnFiber.internalContextTag,
|
||||
priority,
|
||||
);
|
||||
created.type = yieldNode.value;
|
||||
created.return = returnFiber;
|
||||
return created;
|
||||
|
@ -1127,7 +1210,11 @@ function ChildReconciler(shouldClone, shouldTrackSideEffects) {
|
|||
child = child.sibling;
|
||||
}
|
||||
|
||||
const created = createFiberFromPortal(portal, priority);
|
||||
const created = createFiberFromPortal(
|
||||
portal,
|
||||
returnFiber.internalContextTag,
|
||||
priority,
|
||||
);
|
||||
created.return = returnFiber;
|
||||
return created;
|
||||
}
|
||||
|
@ -1228,7 +1315,8 @@ function ChildReconciler(shouldClone, shouldTrackSideEffects) {
|
|||
if (__DEV__) {
|
||||
const instance = returnFiber.stateNode;
|
||||
if (
|
||||
instance.render._isMockFunction && typeof newChild === 'undefined'
|
||||
instance.render._isMockFunction &&
|
||||
typeof newChild === 'undefined'
|
||||
) {
|
||||
// We allow auto-mocks to proceed as if they're
|
||||
// returning null.
|
||||
|
@ -1361,10 +1449,10 @@ exports.cloneChildFibers = function(
|
|||
newChild.return = workInProgress;
|
||||
while (currentChild.sibling !== null) {
|
||||
currentChild = currentChild.sibling;
|
||||
newChild = (newChild.sibling = cloneFiber(
|
||||
newChild = newChild.sibling = cloneFiber(
|
||||
currentChild,
|
||||
currentChild.pendingWorkPriority,
|
||||
));
|
||||
);
|
||||
newChild.return = workInProgress;
|
||||
}
|
||||
newChild.sibling = null;
|
||||
|
|
|
@ -41,7 +41,8 @@ if (__DEV__) {
|
|||
// Longer prefixes are hard to read in DevTools.
|
||||
const reactEmoji = '\u269B';
|
||||
const warningEmoji = '\u26D4';
|
||||
const supportsUserTiming = typeof performance !== 'undefined' &&
|
||||
const supportsUserTiming =
|
||||
typeof performance !== 'undefined' &&
|
||||
typeof performance.mark === 'function' &&
|
||||
typeof performance.clearMarks === 'function' &&
|
||||
typeof performance.measure === 'function' &&
|
||||
|
|
|
@ -18,11 +18,11 @@ import type {ReactFragment} from 'ReactTypes';
|
|||
import type {ReactCoroutine, ReactYield} from 'ReactCoroutine';
|
||||
import type {ReactPortal} from 'ReactPortal';
|
||||
import type {TypeOfWork} from 'ReactTypeOfWork';
|
||||
import type {TypeOfInternalContext} from 'ReactTypeOfInternalContext';
|
||||
import type {TypeOfSideEffect} from 'ReactTypeOfSideEffect';
|
||||
import type {PriorityLevel} from 'ReactPriorityLevel';
|
||||
import type {UpdateQueue} from 'ReactFiberUpdateQueue';
|
||||
|
||||
var ReactTypeOfWork = require('ReactTypeOfWork');
|
||||
var {
|
||||
IndeterminateComponent,
|
||||
ClassComponent,
|
||||
|
@ -33,24 +33,32 @@ var {
|
|||
CoroutineComponent,
|
||||
YieldComponent,
|
||||
Fragment,
|
||||
} = ReactTypeOfWork;
|
||||
} = require('ReactTypeOfWork');
|
||||
|
||||
var {
|
||||
NoWork,
|
||||
} = require('ReactPriorityLevel');
|
||||
var {NoWork} = require('ReactPriorityLevel');
|
||||
|
||||
var {
|
||||
NoEffect,
|
||||
} = require('ReactTypeOfSideEffect');
|
||||
var {NoContext} = require('ReactTypeOfInternalContext');
|
||||
|
||||
var {
|
||||
cloneUpdateQueue,
|
||||
} = require('ReactFiberUpdateQueue');
|
||||
var {NoEffect} = require('ReactTypeOfSideEffect');
|
||||
|
||||
var {cloneUpdateQueue} = require('ReactFiberUpdateQueue');
|
||||
|
||||
var invariant = require('fbjs/lib/invariant');
|
||||
|
||||
if (__DEV__) {
|
||||
var getComponentName = require('getComponentName');
|
||||
|
||||
var hasBadMapPolyfill = false;
|
||||
try {
|
||||
const nonExtensibleObject = Object.preventExtensions({});
|
||||
/* eslint-disable no-new */
|
||||
new Map([[nonExtensibleObject, null]]);
|
||||
new Set([nonExtensibleObject]);
|
||||
/* eslint-enable no-new */
|
||||
} catch (e) {
|
||||
// TODO: Consider warning about bad polyfills
|
||||
hasBadMapPolyfill = true;
|
||||
}
|
||||
}
|
||||
|
||||
// A Fiber is work on a Component that needs to be done or was done. There can
|
||||
|
@ -116,6 +124,14 @@ export type Fiber = {
|
|||
// The state used to create the output
|
||||
memoizedState: any,
|
||||
|
||||
// Bitfield that describes properties about the fiber and its subtree. E.g.
|
||||
// the AsyncUpdates flag indicates whether the subtree should be async-by-
|
||||
// default. When a fiber is created, it inherits the internalContextTag of its
|
||||
// parent. Additional flags can be set at creation time, but after than the
|
||||
// value should remain unchanged throughout the fiber's lifetime, particularly
|
||||
// before its child fibers are created.
|
||||
internalContextTag: TypeOfInternalContext,
|
||||
|
||||
// Effect
|
||||
effectTag: TypeOfSideEffect,
|
||||
|
||||
|
@ -176,7 +192,11 @@ if (__DEV__) {
|
|||
// to optimize in a non-JIT environment.
|
||||
// 5) It should be easy to port this to a C struct and keep a C implementation
|
||||
// compatible.
|
||||
var createFiber = function(tag: TypeOfWork, key: null | string): Fiber {
|
||||
var createFiber = function(
|
||||
tag: TypeOfWork,
|
||||
key: null | string,
|
||||
internalContextTag: TypeOfInternalContext,
|
||||
): Fiber {
|
||||
var fiber: Fiber = {
|
||||
// Instance
|
||||
|
||||
|
@ -203,6 +223,8 @@ var createFiber = function(tag: TypeOfWork, key: null | string): Fiber {
|
|||
updateQueue: null,
|
||||
memoizedState: null,
|
||||
|
||||
internalContextTag,
|
||||
|
||||
effectTag: NoEffect,
|
||||
nextEffect: null,
|
||||
firstEffect: null,
|
||||
|
@ -222,7 +244,7 @@ var createFiber = function(tag: TypeOfWork, key: null | string): Fiber {
|
|||
fiber._debugSource = null;
|
||||
fiber._debugOwner = null;
|
||||
fiber._debugIsCurrentlyTiming = false;
|
||||
if (typeof Object.preventExtensions === 'function') {
|
||||
if (!hasBadMapPolyfill && typeof Object.preventExtensions === 'function') {
|
||||
Object.preventExtensions(fiber);
|
||||
}
|
||||
}
|
||||
|
@ -264,7 +286,7 @@ exports.cloneFiber = function(
|
|||
alt.lastEffect = null;
|
||||
} else {
|
||||
// This should not have an alternate already
|
||||
alt = createFiber(fiber.tag, fiber.key);
|
||||
alt = createFiber(fiber.tag, fiber.key, fiber.internalContextTag);
|
||||
alt.type = fiber.type;
|
||||
|
||||
alt.progressedChild = fiber.progressedChild;
|
||||
|
@ -298,12 +320,13 @@ exports.cloneFiber = function(
|
|||
};
|
||||
|
||||
exports.createHostRootFiber = function(): Fiber {
|
||||
const fiber = createFiber(HostRoot, null);
|
||||
const fiber = createFiber(HostRoot, null, NoContext);
|
||||
return fiber;
|
||||
};
|
||||
|
||||
exports.createFiberFromElement = function(
|
||||
element: ReactElement,
|
||||
internalContextTag: TypeOfInternalContext,
|
||||
priorityLevel: PriorityLevel,
|
||||
): Fiber {
|
||||
let owner = null;
|
||||
|
@ -311,7 +334,12 @@ exports.createFiberFromElement = function(
|
|||
owner = element._owner;
|
||||
}
|
||||
|
||||
const fiber = createFiberFromElementType(element.type, element.key, owner);
|
||||
const fiber = createFiberFromElementType(
|
||||
element.type,
|
||||
element.key,
|
||||
internalContextTag,
|
||||
owner,
|
||||
);
|
||||
fiber.pendingProps = element.props;
|
||||
fiber.pendingWorkPriority = priorityLevel;
|
||||
|
||||
|
@ -325,11 +353,12 @@ exports.createFiberFromElement = function(
|
|||
|
||||
exports.createFiberFromFragment = function(
|
||||
elements: ReactFragment,
|
||||
internalContextTag: TypeOfInternalContext,
|
||||
priorityLevel: PriorityLevel,
|
||||
): Fiber {
|
||||
// TODO: Consider supporting keyed fragments. Technically, we accidentally
|
||||
// support that in the existing React.
|
||||
const fiber = createFiber(Fragment, null);
|
||||
const fiber = createFiber(Fragment, null, internalContextTag);
|
||||
fiber.pendingProps = elements;
|
||||
fiber.pendingWorkPriority = priorityLevel;
|
||||
return fiber;
|
||||
|
@ -337,9 +366,10 @@ exports.createFiberFromFragment = function(
|
|||
|
||||
exports.createFiberFromText = function(
|
||||
content: string,
|
||||
internalContextTag: TypeOfInternalContext,
|
||||
priorityLevel: PriorityLevel,
|
||||
): Fiber {
|
||||
const fiber = createFiber(HostText, null);
|
||||
const fiber = createFiber(HostText, null, internalContextTag);
|
||||
fiber.pendingProps = content;
|
||||
fiber.pendingWorkPriority = priorityLevel;
|
||||
return fiber;
|
||||
|
@ -348,19 +378,22 @@ exports.createFiberFromText = function(
|
|||
function createFiberFromElementType(
|
||||
type: mixed,
|
||||
key: null | string,
|
||||
internalContextTag: TypeOfInternalContext,
|
||||
debugOwner: null | Fiber | ReactInstance,
|
||||
): Fiber {
|
||||
let fiber;
|
||||
if (typeof type === 'function') {
|
||||
fiber = shouldConstruct(type)
|
||||
? createFiber(ClassComponent, key)
|
||||
: createFiber(IndeterminateComponent, key);
|
||||
? createFiber(ClassComponent, key, internalContextTag)
|
||||
: createFiber(IndeterminateComponent, key, internalContextTag);
|
||||
fiber.type = type;
|
||||
} else if (typeof type === 'string') {
|
||||
fiber = createFiber(HostComponent, key);
|
||||
fiber = createFiber(HostComponent, key, internalContextTag);
|
||||
fiber.type = type;
|
||||
} else if (
|
||||
typeof type === 'object' && type !== null && typeof type.tag === 'number'
|
||||
typeof type === 'object' &&
|
||||
type !== null &&
|
||||
typeof type.tag === 'number'
|
||||
) {
|
||||
// Currently assumed to be a continuation and therefore is a fiber already.
|
||||
// TODO: The yield system is currently broken for updates in some cases.
|
||||
|
@ -378,7 +411,8 @@ function createFiberFromElementType(
|
|||
type !== null &&
|
||||
Object.keys(type).length === 0)
|
||||
) {
|
||||
info += ' You likely forgot to export your component from the file ' +
|
||||
info +=
|
||||
' You likely forgot to export your component from the file ' +
|
||||
"it's defined in.";
|
||||
}
|
||||
const ownerName = debugOwner ? getComponentName(debugOwner) : null;
|
||||
|
@ -401,9 +435,14 @@ exports.createFiberFromElementType = createFiberFromElementType;
|
|||
|
||||
exports.createFiberFromCoroutine = function(
|
||||
coroutine: ReactCoroutine,
|
||||
internalContextTag: TypeOfInternalContext,
|
||||
priorityLevel: PriorityLevel,
|
||||
): Fiber {
|
||||
const fiber = createFiber(CoroutineComponent, coroutine.key);
|
||||
const fiber = createFiber(
|
||||
CoroutineComponent,
|
||||
coroutine.key,
|
||||
internalContextTag,
|
||||
);
|
||||
fiber.type = coroutine.handler;
|
||||
fiber.pendingProps = coroutine;
|
||||
fiber.pendingWorkPriority = priorityLevel;
|
||||
|
@ -412,17 +451,19 @@ exports.createFiberFromCoroutine = function(
|
|||
|
||||
exports.createFiberFromYield = function(
|
||||
yieldNode: ReactYield,
|
||||
internalContextTag: TypeOfInternalContext,
|
||||
priorityLevel: PriorityLevel,
|
||||
): Fiber {
|
||||
const fiber = createFiber(YieldComponent, null);
|
||||
const fiber = createFiber(YieldComponent, null, internalContextTag);
|
||||
return fiber;
|
||||
};
|
||||
|
||||
exports.createFiberFromPortal = function(
|
||||
portal: ReactPortal,
|
||||
internalContextTag: TypeOfInternalContext,
|
||||
priorityLevel: PriorityLevel,
|
||||
): Fiber {
|
||||
const fiber = createFiber(HostPortal, portal.key);
|
||||
const fiber = createFiber(HostPortal, portal.key, internalContextTag);
|
||||
fiber.pendingProps = portal.children || [];
|
||||
fiber.pendingWorkPriority = priorityLevel;
|
||||
fiber.stateNode = {
|
||||
|
|
|
@ -25,9 +25,7 @@ var {
|
|||
reconcileChildFibersInPlace,
|
||||
cloneChildFibers,
|
||||
} = require('ReactChildFiber');
|
||||
var {
|
||||
beginUpdateQueue,
|
||||
} = require('ReactFiberUpdateQueue');
|
||||
var {beginUpdateQueue} = require('ReactFiberUpdateQueue');
|
||||
var ReactTypeOfWork = require('ReactTypeOfWork');
|
||||
var {
|
||||
getMaskedContext,
|
||||
|
@ -50,18 +48,10 @@ var {
|
|||
YieldComponent,
|
||||
Fragment,
|
||||
} = ReactTypeOfWork;
|
||||
var {
|
||||
NoWork,
|
||||
OffscreenPriority,
|
||||
} = require('ReactPriorityLevel');
|
||||
var {
|
||||
Placement,
|
||||
ContentReset,
|
||||
Err,
|
||||
Ref,
|
||||
} = require('ReactTypeOfSideEffect');
|
||||
var ReactCurrentOwner = require('react/lib/ReactCurrentOwner');
|
||||
var {NoWork, OffscreenPriority} = require('ReactPriorityLevel');
|
||||
var {Placement, ContentReset, Err, Ref} = require('ReactTypeOfSideEffect');
|
||||
var ReactFiberClassComponent = require('ReactFiberClassComponent');
|
||||
var {ReactCurrentOwner} = require('ReactGlobalSharedState');
|
||||
var invariant = require('fbjs/lib/invariant');
|
||||
|
||||
if (__DEV__) {
|
||||
|
@ -76,7 +66,7 @@ module.exports = function<T, P, I, TI, PI, C, CX, PL>(
|
|||
config: HostConfig<T, P, I, TI, PI, C, CX, PL>,
|
||||
hostContext: HostContext<C, CX>,
|
||||
scheduleUpdate: (fiber: Fiber, priorityLevel: PriorityLevel) => void,
|
||||
getPriorityContext: () => PriorityLevel,
|
||||
getPriorityContext: (fiber: Fiber, forceAsync: boolean) => PriorityLevel,
|
||||
) {
|
||||
const {
|
||||
shouldSetTextContent,
|
||||
|
@ -84,10 +74,7 @@ module.exports = function<T, P, I, TI, PI, C, CX, PL>(
|
|||
shouldDeprioritizeSubtree,
|
||||
} = config;
|
||||
|
||||
const {
|
||||
pushHostContext,
|
||||
pushHostContainer,
|
||||
} = hostContext;
|
||||
const {pushHostContext, pushHostContainer} = hostContext;
|
||||
|
||||
const {
|
||||
adoptClassInstance,
|
||||
|
@ -115,7 +102,7 @@ module.exports = function<T, P, I, TI, PI, C, CX, PL>(
|
|||
}
|
||||
|
||||
function clearDeletions(workInProgress) {
|
||||
workInProgress.progressedFirstDeletion = (workInProgress.progressedLastDeletion = null);
|
||||
workInProgress.progressedFirstDeletion = workInProgress.progressedLastDeletion = null;
|
||||
}
|
||||
|
||||
function transferDeletions(workInProgress) {
|
||||
|
@ -196,7 +183,8 @@ module.exports = function<T, P, I, TI, PI, C, CX, PL>(
|
|||
nextChildren = workInProgress.memoizedProps;
|
||||
}
|
||||
} else if (
|
||||
nextChildren === null || workInProgress.memoizedProps === nextChildren
|
||||
nextChildren === null ||
|
||||
workInProgress.memoizedProps === nextChildren
|
||||
) {
|
||||
return bailoutOnAlreadyFinishedWork(current, workInProgress);
|
||||
}
|
||||
|
@ -272,7 +260,7 @@ module.exports = function<T, P, I, TI, PI, C, CX, PL>(
|
|||
if (current === null) {
|
||||
if (!workInProgress.stateNode) {
|
||||
// In the initial pass we might need to construct the instance.
|
||||
constructClassInstance(workInProgress);
|
||||
constructClassInstance(workInProgress, workInProgress.pendingProps);
|
||||
mountClassInstance(workInProgress, priorityLevel);
|
||||
shouldUpdate = true;
|
||||
} else {
|
||||
|
@ -585,7 +573,8 @@ module.exports = function<T, P, I, TI, PI, C, CX, PL>(
|
|||
);
|
||||
}
|
||||
} else if (
|
||||
nextCoroutine === null || workInProgress.memoizedProps === nextCoroutine
|
||||
nextCoroutine === null ||
|
||||
workInProgress.memoizedProps === nextCoroutine
|
||||
) {
|
||||
nextCoroutine = workInProgress.memoizedProps;
|
||||
// TODO: When bailing out, we might need to return the stateNode instead
|
||||
|
@ -653,7 +642,8 @@ module.exports = function<T, P, I, TI, PI, C, CX, PL>(
|
|||
);
|
||||
}
|
||||
} else if (
|
||||
nextChildren === null || workInProgress.memoizedProps === nextChildren
|
||||
nextChildren === null ||
|
||||
workInProgress.memoizedProps === nextChildren
|
||||
) {
|
||||
return bailoutOnAlreadyFinishedWork(current, workInProgress);
|
||||
}
|
||||
|
|
|
@ -15,9 +15,11 @@
|
|||
import type {Fiber} from 'ReactFiber';
|
||||
import type {PriorityLevel} from 'ReactPriorityLevel';
|
||||
|
||||
var {
|
||||
Update,
|
||||
} = require('ReactTypeOfSideEffect');
|
||||
var {Update} = require('ReactTypeOfSideEffect');
|
||||
|
||||
var ReactFeatureFlags = require('ReactFeatureFlags');
|
||||
var {AsyncUpdates} = require('ReactTypeOfInternalContext');
|
||||
|
||||
var {
|
||||
cacheContext,
|
||||
getMaskedContext,
|
||||
|
@ -41,10 +43,7 @@ var invariant = require('fbjs/lib/invariant');
|
|||
const isArray = Array.isArray;
|
||||
|
||||
if (__DEV__) {
|
||||
var {
|
||||
startPhaseTimer,
|
||||
stopPhaseTimer,
|
||||
} = require('ReactDebugFiberPerf');
|
||||
var {startPhaseTimer, stopPhaseTimer} = require('ReactDebugFiberPerf');
|
||||
var warning = require('fbjs/lib/warning');
|
||||
var warnOnInvalidCallback = function(callback: mixed, callerName: string) {
|
||||
warning(
|
||||
|
@ -59,7 +58,7 @@ if (__DEV__) {
|
|||
|
||||
module.exports = function(
|
||||
scheduleUpdate: (fiber: Fiber, priorityLevel: PriorityLevel) => void,
|
||||
getPriorityContext: () => PriorityLevel,
|
||||
getPriorityContext: (fiber: Fiber, forceAsync: boolean) => PriorityLevel,
|
||||
memoizeProps: (workInProgress: Fiber, props: any) => void,
|
||||
memoizeState: (workInProgress: Fiber, state: any) => void,
|
||||
) {
|
||||
|
@ -68,7 +67,7 @@ module.exports = function(
|
|||
isMounted,
|
||||
enqueueSetState(instance, partialState, callback) {
|
||||
const fiber = ReactInstanceMap.get(instance);
|
||||
const priorityLevel = getPriorityContext();
|
||||
const priorityLevel = getPriorityContext(fiber, false);
|
||||
callback = callback === undefined ? null : callback;
|
||||
if (__DEV__) {
|
||||
warnOnInvalidCallback(callback, 'setState');
|
||||
|
@ -78,7 +77,7 @@ module.exports = function(
|
|||
},
|
||||
enqueueReplaceState(instance, state, callback) {
|
||||
const fiber = ReactInstanceMap.get(instance);
|
||||
const priorityLevel = getPriorityContext();
|
||||
const priorityLevel = getPriorityContext(fiber, false);
|
||||
callback = callback === undefined ? null : callback;
|
||||
if (__DEV__) {
|
||||
warnOnInvalidCallback(callback, 'replaceState');
|
||||
|
@ -88,7 +87,7 @@ module.exports = function(
|
|||
},
|
||||
enqueueForceUpdate(instance, callback) {
|
||||
const fiber = ReactInstanceMap.get(instance);
|
||||
const priorityLevel = getPriorityContext();
|
||||
const priorityLevel = getPriorityContext(fiber, false);
|
||||
callback = callback === undefined ? null : callback;
|
||||
if (__DEV__) {
|
||||
warnOnInvalidCallback(callback, 'forceUpdate');
|
||||
|
@ -116,6 +115,7 @@ module.exports = function(
|
|||
}
|
||||
|
||||
const instance = workInProgress.stateNode;
|
||||
const type = workInProgress.type;
|
||||
if (typeof instance.shouldComponentUpdate === 'function') {
|
||||
if (__DEV__) {
|
||||
startPhaseTimer(workInProgress, 'shouldComponentUpdate');
|
||||
|
@ -141,10 +141,10 @@ module.exports = function(
|
|||
return shouldUpdate;
|
||||
}
|
||||
|
||||
const type = workInProgress.type;
|
||||
if (type.prototype && type.prototype.isPureReactComponent) {
|
||||
return !shallowEqual(oldProps, newProps) ||
|
||||
!shallowEqual(oldState, newState);
|
||||
return (
|
||||
!shallowEqual(oldProps, newProps) || !shallowEqual(oldState, newState)
|
||||
);
|
||||
}
|
||||
|
||||
return true;
|
||||
|
@ -152,6 +152,7 @@ module.exports = function(
|
|||
|
||||
function checkClassInstance(workInProgress: Fiber) {
|
||||
const instance = workInProgress.stateNode;
|
||||
const type = workInProgress.type;
|
||||
if (__DEV__) {
|
||||
const name = getComponentName(workInProgress);
|
||||
const renderPresent = instance.render;
|
||||
|
@ -161,7 +162,8 @@ module.exports = function(
|
|||
'instance: you may have forgotten to define `render`.',
|
||||
name,
|
||||
);
|
||||
const noGetInitialStateOnES6 = !instance.getInitialState ||
|
||||
const noGetInitialStateOnES6 =
|
||||
!instance.getInitialState ||
|
||||
instance.getInitialState.isReactClassApproved ||
|
||||
instance.state;
|
||||
warning(
|
||||
|
@ -171,7 +173,8 @@ module.exports = function(
|
|||
'Did you mean to define a state property instead?',
|
||||
name,
|
||||
);
|
||||
const noGetDefaultPropsOnES6 = !instance.getDefaultProps ||
|
||||
const noGetDefaultPropsOnES6 =
|
||||
!instance.getDefaultProps ||
|
||||
instance.getDefaultProps.isReactClassApproved;
|
||||
warning(
|
||||
noGetDefaultPropsOnES6,
|
||||
|
@ -194,8 +197,8 @@ module.exports = function(
|
|||
'property to define contextTypes instead.',
|
||||
name,
|
||||
);
|
||||
const noComponentShouldUpdate = typeof instance.componentShouldUpdate !==
|
||||
'function';
|
||||
const noComponentShouldUpdate =
|
||||
typeof instance.componentShouldUpdate !== 'function';
|
||||
warning(
|
||||
noComponentShouldUpdate,
|
||||
'%s has a method called ' +
|
||||
|
@ -204,8 +207,21 @@ module.exports = function(
|
|||
'expected to return a value.',
|
||||
name,
|
||||
);
|
||||
const noComponentDidUnmount = typeof instance.componentDidUnmount !==
|
||||
'function';
|
||||
if (
|
||||
type.prototype &&
|
||||
type.prototype.isPureReactComponent &&
|
||||
typeof instance.shouldComponentUpdate !== 'undefined'
|
||||
) {
|
||||
warning(
|
||||
false,
|
||||
'%s has a method called shouldComponentUpdate(). ' +
|
||||
'shouldComponentUpdate should not be used when extending React.PureComponent. ' +
|
||||
'Please extend React.Component if shouldComponentUpdate is used.',
|
||||
getComponentName(workInProgress) || 'A pure component',
|
||||
);
|
||||
}
|
||||
const noComponentDidUnmount =
|
||||
typeof instance.componentDidUnmount !== 'function';
|
||||
warning(
|
||||
noComponentDidUnmount,
|
||||
'%s has a method called ' +
|
||||
|
@ -213,8 +229,8 @@ module.exports = function(
|
|||
'Did you mean componentWillUnmount()?',
|
||||
name,
|
||||
);
|
||||
const noComponentWillRecieveProps = typeof instance.componentWillRecieveProps !==
|
||||
'function';
|
||||
const noComponentWillRecieveProps =
|
||||
typeof instance.componentWillRecieveProps !== 'function';
|
||||
warning(
|
||||
noComponentWillRecieveProps,
|
||||
'%s has a method called ' +
|
||||
|
@ -229,6 +245,14 @@ module.exports = function(
|
|||
name,
|
||||
name,
|
||||
);
|
||||
const noInstanceDefaultProps = !instance.defaultProps;
|
||||
warning(
|
||||
noInstanceDefaultProps,
|
||||
'Setting defaultProps as an instance property on %s is not supported and will be ignored.' +
|
||||
' Instead, define defaultProps as a static property on %s.',
|
||||
name,
|
||||
name,
|
||||
);
|
||||
}
|
||||
|
||||
const state = instance.state;
|
||||
|
@ -261,9 +285,8 @@ module.exports = function(
|
|||
ReactInstanceMap.set(instance, workInProgress);
|
||||
}
|
||||
|
||||
function constructClassInstance(workInProgress: Fiber): any {
|
||||
function constructClassInstance(workInProgress: Fiber, props: any): any {
|
||||
const ctor = workInProgress.type;
|
||||
const props = workInProgress.pendingProps;
|
||||
const unmaskedContext = getUnmaskedContext(workInProgress);
|
||||
const needsContext = isContextConsumer(workInProgress);
|
||||
const context = needsContext
|
||||
|
@ -271,7 +294,6 @@ module.exports = function(
|
|||
: emptyObject;
|
||||
const instance = new ctor(props, context);
|
||||
adoptClassInstance(workInProgress, instance);
|
||||
checkClassInstance(workInProgress);
|
||||
|
||||
// Cache unmasked context so we can avoid recreating masked context unless necessary.
|
||||
// ReactFiberContext usually updates this cache but can't for newly-created instances.
|
||||
|
@ -287,6 +309,10 @@ module.exports = function(
|
|||
workInProgress: Fiber,
|
||||
priorityLevel: PriorityLevel,
|
||||
): void {
|
||||
if (__DEV__) {
|
||||
checkClassInstance(workInProgress);
|
||||
}
|
||||
|
||||
const instance = workInProgress.stateNode;
|
||||
const state = instance.state || null;
|
||||
|
||||
|
@ -304,6 +330,14 @@ module.exports = function(
|
|||
instance.refs = emptyObject;
|
||||
instance.context = getMaskedContext(workInProgress, unmaskedContext);
|
||||
|
||||
if (
|
||||
ReactFeatureFlags.enableAsyncSubtreeAPI &&
|
||||
workInProgress.type != null &&
|
||||
workInProgress.type.unstable_asyncUpdates === true
|
||||
) {
|
||||
workInProgress.internalContextTag |= AsyncUpdates;
|
||||
}
|
||||
|
||||
if (typeof instance.componentWillMount === 'function') {
|
||||
if (__DEV__) {
|
||||
startPhaseTimer(workInProgress, 'componentWillMount');
|
||||
|
@ -379,9 +413,9 @@ module.exports = function(
|
|||
|
||||
// If we didn't bail out we need to construct a new instance. We don't
|
||||
// want to reuse one that failed to fully mount.
|
||||
const newInstance = constructClassInstance(workInProgress);
|
||||
const newInstance = constructClassInstance(workInProgress, newProps);
|
||||
newInstance.props = newProps;
|
||||
newInstance.state = (newState = newInstance.state || null);
|
||||
newInstance.state = newState = newInstance.state || null;
|
||||
newInstance.context = newContext;
|
||||
|
||||
if (typeof newInstance.componentWillMount === 'function') {
|
||||
|
|
|
@ -38,10 +38,7 @@ var {
|
|||
var invariant = require('fbjs/lib/invariant');
|
||||
|
||||
if (__DEV__) {
|
||||
var {
|
||||
startPhaseTimer,
|
||||
stopPhaseTimer,
|
||||
} = require('ReactDebugFiberPerf');
|
||||
var {startPhaseTimer, stopPhaseTimer} = require('ReactDebugFiberPerf');
|
||||
}
|
||||
|
||||
module.exports = function<T, P, I, TI, PI, C, CX, PL>(
|
||||
|
@ -143,9 +140,11 @@ module.exports = function<T, P, I, TI, PI, C, CX, PL>(
|
|||
}
|
||||
|
||||
function isHostParent(fiber: Fiber): boolean {
|
||||
return fiber.tag === HostComponent ||
|
||||
return (
|
||||
fiber.tag === HostComponent ||
|
||||
fiber.tag === HostRoot ||
|
||||
fiber.tag === HostPortal;
|
||||
fiber.tag === HostPortal
|
||||
);
|
||||
}
|
||||
|
||||
function getHostSibling(fiber: Fiber): ?I {
|
||||
|
@ -468,7 +467,8 @@ module.exports = function<T, P, I, TI, PI, C, CX, PL>(
|
|||
}
|
||||
}
|
||||
if (
|
||||
finishedWork.effectTag & Callback && finishedWork.updateQueue !== null
|
||||
finishedWork.effectTag & Callback &&
|
||||
finishedWork.updateQueue !== null
|
||||
) {
|
||||
commitCallbacks(finishedWork, finishedWork.updateQueue, instance);
|
||||
}
|
||||
|
|
|
@ -19,9 +19,7 @@ import type {FiberRoot} from 'ReactFiberRoot';
|
|||
import type {HostConfig} from 'ReactFiberReconciler';
|
||||
|
||||
var {reconcileChildFibers} = require('ReactChildFiber');
|
||||
var {
|
||||
popContextProvider,
|
||||
} = require('ReactFiberContext');
|
||||
var {popContextProvider} = require('ReactFiberContext');
|
||||
var ReactTypeOfWork = require('ReactTypeOfWork');
|
||||
var ReactTypeOfSideEffect = require('ReactTypeOfSideEffect');
|
||||
var {
|
||||
|
@ -37,10 +35,7 @@ var {
|
|||
YieldComponent,
|
||||
Fragment,
|
||||
} = ReactTypeOfWork;
|
||||
var {
|
||||
Ref,
|
||||
Update,
|
||||
} = ReactTypeOfSideEffect;
|
||||
var {Ref, Update} = ReactTypeOfSideEffect;
|
||||
|
||||
if (__DEV__) {
|
||||
var ReactDebugCurrentFiber = require('ReactDebugCurrentFiber');
|
||||
|
@ -342,7 +337,6 @@ module.exports = function<T, P, I, TI, PI, C, CX, PL>(
|
|||
markUpdate(workInProgress);
|
||||
popHostContainer(workInProgress);
|
||||
return null;
|
||||
|
||||
// Error cases
|
||||
case IndeterminateComponent:
|
||||
invariant(
|
||||
|
|
|
@ -15,31 +15,19 @@
|
|||
import type {Fiber} from 'ReactFiber';
|
||||
import type {StackCursor} from 'ReactFiberStack';
|
||||
|
||||
var checkPropTypes = require('prop-types/checkPropTypes');
|
||||
var emptyObject = require('fbjs/lib/emptyObject');
|
||||
var getComponentName = require('getComponentName');
|
||||
var invariant = require('fbjs/lib/invariant');
|
||||
var warning = require('fbjs/lib/warning');
|
||||
var {
|
||||
isFiberMounted,
|
||||
} = require('ReactFiberTreeReflection');
|
||||
var {
|
||||
ClassComponent,
|
||||
HostRoot,
|
||||
} = require('ReactTypeOfWork');
|
||||
const {
|
||||
createCursor,
|
||||
pop,
|
||||
push,
|
||||
} = require('ReactFiberStack');
|
||||
var {isFiberMounted} = require('ReactFiberTreeReflection');
|
||||
var {ClassComponent, HostRoot} = require('ReactTypeOfWork');
|
||||
const {createCursor, pop, push} = require('ReactFiberStack');
|
||||
|
||||
if (__DEV__) {
|
||||
var checkReactTypeSpec = require('checkReactTypeSpec');
|
||||
var ReactDebugCurrentFrame = require('react/lib/ReactDebugCurrentFrame');
|
||||
var ReactDebugCurrentFiber = require('ReactDebugCurrentFiber');
|
||||
var {
|
||||
startPhaseTimer,
|
||||
stopPhaseTimer,
|
||||
} = require('ReactDebugFiberPerf');
|
||||
var {ReactDebugCurrentFrame} = require('ReactGlobalSharedState');
|
||||
var {startPhaseTimer, stopPhaseTimer} = require('ReactDebugFiberPerf');
|
||||
var warnedAboutMissingGetChildContext = {};
|
||||
}
|
||||
|
||||
|
@ -105,7 +93,13 @@ exports.getMaskedContext = function(
|
|||
if (__DEV__) {
|
||||
const name = getComponentName(workInProgress) || 'Unknown';
|
||||
ReactDebugCurrentFrame.current = workInProgress;
|
||||
checkReactTypeSpec(contextTypes, context, 'context', name);
|
||||
checkPropTypes(
|
||||
contextTypes,
|
||||
context,
|
||||
'context',
|
||||
name,
|
||||
ReactDebugCurrentFrame.getStackAddendum,
|
||||
);
|
||||
ReactDebugCurrentFrame.current = null;
|
||||
}
|
||||
|
||||
|
@ -212,7 +206,13 @@ function processChildContext(
|
|||
// TODO: remove this hack when we delete unstable_renderSubtree in Fiber.
|
||||
const workInProgress = isReconciling ? fiber : null;
|
||||
ReactDebugCurrentFrame.current = workInProgress;
|
||||
checkReactTypeSpec(childContextTypes, childContext, 'child context', name);
|
||||
checkPropTypes(
|
||||
childContextTypes,
|
||||
childContext,
|
||||
'child context',
|
||||
name,
|
||||
ReactDebugCurrentFrame.getStackAddendum,
|
||||
);
|
||||
ReactDebugCurrentFrame.current = null;
|
||||
}
|
||||
|
||||
|
@ -229,8 +229,8 @@ exports.pushContextProvider = function(workInProgress: Fiber): boolean {
|
|||
// We push the context as early as possible to ensure stack integrity.
|
||||
// If the instance does not exist yet, we will push null at first,
|
||||
// and replace it on the stack later when invalidating the context.
|
||||
const memoizedMergedChildContext = (instance &&
|
||||
instance.__reactInternalMemoizedMergedChildContext) ||
|
||||
const memoizedMergedChildContext =
|
||||
(instance && instance.__reactInternalMemoizedMergedChildContext) ||
|
||||
emptyObject;
|
||||
|
||||
// Remember the parent context so we can merge with it later.
|
||||
|
|
|
@ -39,11 +39,7 @@ function logCapturedError(capturedError: CapturedError): void {
|
|||
willRetry,
|
||||
} = capturedError;
|
||||
|
||||
const {
|
||||
message,
|
||||
name,
|
||||
stack,
|
||||
} = error;
|
||||
const {message, name, stack} = error;
|
||||
|
||||
const errorSummary = message ? `${name}: ${message}` : name;
|
||||
|
||||
|
@ -69,15 +65,18 @@ function logCapturedError(capturedError: CapturedError): void {
|
|||
// errorBoundaryFound check is sufficient; errorBoundaryName check is to satisfy Flow.
|
||||
if (errorBoundaryFound && errorBoundaryName) {
|
||||
if (willRetry) {
|
||||
errorBoundaryMessage = `React will try to recreate this component tree from scratch ` +
|
||||
errorBoundaryMessage =
|
||||
`React will try to recreate this component tree from scratch ` +
|
||||
`using the error boundary you provided, ${errorBoundaryName}.`;
|
||||
} else {
|
||||
errorBoundaryMessage = `This error was initially handled by the error boundary ${errorBoundaryName}. ` +
|
||||
errorBoundaryMessage =
|
||||
`This error was initially handled by the error boundary ${errorBoundaryName}. ` +
|
||||
`Recreating the tree from scratch failed so React will unmount the tree.`;
|
||||
}
|
||||
} else {
|
||||
// TODO Link to unstable_handleError() documentation once it exists.
|
||||
errorBoundaryMessage = 'Consider adding an error boundary to your tree to customize error handling behavior.';
|
||||
errorBoundaryMessage =
|
||||
'Consider adding an error boundary to your tree to customize error handling behavior.';
|
||||
}
|
||||
|
||||
console.error(
|
||||
|
@ -98,7 +97,7 @@ function logCapturedError(capturedError: CapturedError): void {
|
|||
|
||||
exports.injection = {
|
||||
/**
|
||||
* Display custom dialog for lifecycle errors.
|
||||
* Display custom dialog for lifecycle errors.
|
||||
* Return false to prevent default behavior of logging to console.error.
|
||||
*/
|
||||
injectDialog(fn: (e: CapturedError) => boolean) {
|
||||
|
|
|
@ -16,16 +16,13 @@ import type {Fiber} from 'ReactFiber';
|
|||
import type {HostConfig} from 'ReactFiberReconciler';
|
||||
import type {StackCursor} from 'ReactFiberStack';
|
||||
|
||||
const emptyObject = require('fbjs/lib/emptyObject');
|
||||
|
||||
const {
|
||||
createCursor,
|
||||
pop,
|
||||
push,
|
||||
} = require('ReactFiberStack');
|
||||
const {createCursor, pop, push} = require('ReactFiberStack');
|
||||
|
||||
const invariant = require('fbjs/lib/invariant');
|
||||
|
||||
declare class NoContextT {}
|
||||
const NO_CONTEXT: NoContextT = ({}: any);
|
||||
|
||||
export type HostContext<C, CX> = {
|
||||
getHostContext(): CX,
|
||||
getRootHostContainer(): C,
|
||||
|
@ -39,24 +36,29 @@ export type HostContext<C, CX> = {
|
|||
module.exports = function<T, P, I, TI, PI, C, CX, PL>(
|
||||
config: HostConfig<T, P, I, TI, PI, C, CX, PL>,
|
||||
): HostContext<C, CX> {
|
||||
const {
|
||||
getChildHostContext,
|
||||
getRootHostContext,
|
||||
} = config;
|
||||
const {getChildHostContext, getRootHostContext} = config;
|
||||
|
||||
let contextStackCursor: StackCursor<CX | null> = createCursor((null: ?CX));
|
||||
let contextFiberStackCursor: StackCursor<Fiber | null> = createCursor(
|
||||
(null: Fiber | null),
|
||||
let contextStackCursor: StackCursor<CX | NoContextT> = createCursor(
|
||||
NO_CONTEXT,
|
||||
);
|
||||
let rootInstanceStackCursor: StackCursor<C | null> = createCursor((null: ?C));
|
||||
let contextFiberStackCursor: StackCursor<Fiber | NoContextT> = createCursor(
|
||||
NO_CONTEXT,
|
||||
);
|
||||
let rootInstanceStackCursor: StackCursor<C | NoContextT> = createCursor(
|
||||
NO_CONTEXT,
|
||||
);
|
||||
|
||||
function requiredContext<Value>(c: Value | NoContextT): Value {
|
||||
invariant(
|
||||
c !== NO_CONTEXT,
|
||||
'Expected host context to exist. This error is likely caused by a bug ' +
|
||||
'in React. Please file an issue.',
|
||||
);
|
||||
return (c: any);
|
||||
}
|
||||
|
||||
function getRootHostContainer(): C {
|
||||
const rootInstance = rootInstanceStackCursor.current;
|
||||
invariant(
|
||||
rootInstance !== null,
|
||||
'Expected root container to exist. This error is likely caused by a ' +
|
||||
'bug in React. Please file an issue.',
|
||||
);
|
||||
const rootInstance = requiredContext(rootInstanceStackCursor.current);
|
||||
return rootInstance;
|
||||
}
|
||||
|
||||
|
@ -80,26 +82,13 @@ module.exports = function<T, P, I, TI, PI, C, CX, PL>(
|
|||
}
|
||||
|
||||
function getHostContext(): CX {
|
||||
const context = contextStackCursor.current;
|
||||
invariant(
|
||||
context != null,
|
||||
'Expected host context to exist. This error is likely caused by a bug ' +
|
||||
'in React. Please file an issue.',
|
||||
);
|
||||
const context = requiredContext(contextStackCursor.current);
|
||||
return context;
|
||||
}
|
||||
|
||||
function pushHostContext(fiber: Fiber): void {
|
||||
const rootInstance = rootInstanceStackCursor.current;
|
||||
invariant(
|
||||
rootInstance != null,
|
||||
'Expected root host context to exist. This error is likely caused by ' +
|
||||
'a bug in React. Please file an issue.',
|
||||
);
|
||||
|
||||
const context = contextStackCursor.current !== null
|
||||
? contextStackCursor.current
|
||||
: emptyObject;
|
||||
const rootInstance = requiredContext(rootInstanceStackCursor.current);
|
||||
const context = requiredContext(contextStackCursor.current);
|
||||
const nextContext = getChildHostContext(context, fiber.type, rootInstance);
|
||||
|
||||
// Don't push this Fiber's context unless it's unique.
|
||||
|
@ -125,8 +114,8 @@ module.exports = function<T, P, I, TI, PI, C, CX, PL>(
|
|||
}
|
||||
|
||||
function resetHostContainer() {
|
||||
contextStackCursor.current = null;
|
||||
rootInstanceStackCursor.current = null;
|
||||
contextStackCursor.current = NO_CONTEXT;
|
||||
rootInstanceStackCursor.current = NO_CONTEXT;
|
||||
}
|
||||
|
||||
return {
|
||||
|
|
|
@ -17,9 +17,9 @@ import type {FiberRoot} from 'ReactFiberRoot';
|
|||
import type {PriorityLevel} from 'ReactPriorityLevel';
|
||||
import type {ReactNodeList} from 'ReactTypes';
|
||||
|
||||
var {
|
||||
addTopLevelUpdate,
|
||||
} = require('ReactFiberUpdateQueue');
|
||||
var ReactFeatureFlags = require('ReactFeatureFlags');
|
||||
|
||||
var {addTopLevelUpdate} = require('ReactFiberUpdateQueue');
|
||||
|
||||
var {
|
||||
findCurrentUnmaskedContext,
|
||||
|
@ -107,9 +107,9 @@ export type HostConfig<T, P, I, TI, PI, C, CX, PL> = {
|
|||
removeChild(parentInstance: I | C, child: I | TI): void,
|
||||
|
||||
scheduleAnimationCallback(callback: () => void): number | void,
|
||||
scheduleDeferredCallback(callback: (deadline: Deadline) => void):
|
||||
| number
|
||||
| void,
|
||||
scheduleDeferredCallback(
|
||||
callback: (deadline: Deadline) => void,
|
||||
): number | void,
|
||||
|
||||
prepareForCommit(): void,
|
||||
resetAfterCommit(): void,
|
||||
|
@ -123,6 +123,7 @@ export type Reconciler<C, I, TI> = {
|
|||
element: ReactNodeList,
|
||||
container: OpaqueRoot,
|
||||
parentComponent: ?ReactComponent<any, any, any>,
|
||||
callback: ?Function,
|
||||
): void,
|
||||
performWithPriority(priorityLevel: PriorityLevel, fn: Function): void,
|
||||
batchedUpdates<A>(fn: () => A): A,
|
||||
|
@ -131,11 +132,9 @@ export type Reconciler<C, I, TI> = {
|
|||
deferredUpdates<A>(fn: () => A): A,
|
||||
|
||||
// Used to extract the return value from the initial render. Legacy API.
|
||||
getPublicRootInstance(container: OpaqueRoot):
|
||||
| ReactComponent<any, any, any>
|
||||
| TI
|
||||
| I
|
||||
| null,
|
||||
getPublicRootInstance(
|
||||
container: OpaqueRoot,
|
||||
): ReactComponent<any, any, any> | TI | I | null,
|
||||
|
||||
// Use for findDOMNode/findHostNode. Legacy API.
|
||||
findHostInstance(component: Fiber): I | TI | null,
|
||||
|
@ -182,7 +181,15 @@ module.exports = function<T, P, I, TI, PI, C, CX, PL>(
|
|||
}
|
||||
}
|
||||
|
||||
const priorityLevel = getPriorityContext();
|
||||
// Check if the top-level element is an async wrapper component. If so, treat
|
||||
// updates to the root as async. This is a bit weird but lets us avoid a separate
|
||||
// `renderAsync` API.
|
||||
const forceAsync =
|
||||
(ReactFeatureFlags : any).enableAsyncSubtreeAPI &&
|
||||
element != null &&
|
||||
element.type != null &&
|
||||
(element.type: any).unstable_asyncUpdates === true;
|
||||
const priorityLevel = getPriorityContext(current, forceAsync);
|
||||
const nextState = {element};
|
||||
callback = callback === undefined ? null : callback;
|
||||
if (__DEV__) {
|
||||
|
|
|
@ -31,9 +31,7 @@ export type HandleErrorInfo = {
|
|||
componentStack: string,
|
||||
};
|
||||
|
||||
var {
|
||||
popContextProvider,
|
||||
} = require('ReactFiberContext');
|
||||
var {popContextProvider} = require('ReactFiberContext');
|
||||
const {reset} = require('ReactFiberStack');
|
||||
var {
|
||||
getStackAddendumByWorkInProgressFiber,
|
||||
|
@ -45,8 +43,8 @@ var ReactFiberBeginWork = require('ReactFiberBeginWork');
|
|||
var ReactFiberCompleteWork = require('ReactFiberCompleteWork');
|
||||
var ReactFiberCommitWork = require('ReactFiberCommitWork');
|
||||
var ReactFiberHostContext = require('ReactFiberHostContext');
|
||||
var ReactCurrentOwner = require('react/lib/ReactCurrentOwner');
|
||||
var ReactFeatureFlags = require('ReactFeatureFlags');
|
||||
var {ReactCurrentOwner} = require('ReactGlobalSharedState');
|
||||
var getComponentName = require('getComponentName');
|
||||
|
||||
var {cloneFiber} = require('ReactFiber');
|
||||
|
@ -62,6 +60,8 @@ var {
|
|||
OffscreenPriority,
|
||||
} = require('ReactPriorityLevel');
|
||||
|
||||
var {AsyncUpdates} = require('ReactTypeOfInternalContext');
|
||||
|
||||
var {
|
||||
NoEffect,
|
||||
Placement,
|
||||
|
@ -81,13 +81,9 @@ var {
|
|||
ClassComponent,
|
||||
} = require('ReactTypeOfWork');
|
||||
|
||||
var {
|
||||
getPendingPriority,
|
||||
} = require('ReactFiberUpdateQueue');
|
||||
var {getPendingPriority} = require('ReactFiberUpdateQueue');
|
||||
|
||||
var {
|
||||
resetContext,
|
||||
} = require('ReactFiberContext');
|
||||
var {resetContext} = require('ReactFiberContext');
|
||||
|
||||
var invariant = require('fbjs/lib/invariant');
|
||||
|
||||
|
@ -173,11 +169,11 @@ module.exports = function<T, P, I, TI, PI, C, CX, PL>(
|
|||
resetAfterCommit,
|
||||
} = config;
|
||||
|
||||
// The priority level to use when scheduling an update.
|
||||
// TODO: Should we change this to an array? Might be less confusing.
|
||||
let priorityContext: PriorityLevel = useSyncScheduling
|
||||
? SynchronousPriority
|
||||
: LowPriority;
|
||||
// The priority level to use when scheduling an update. We use NoWork to
|
||||
// represent the default priority.
|
||||
// TODO: Should we change this to an array instead of using the call stack?
|
||||
// Might be less confusing.
|
||||
let priorityContext: PriorityLevel = NoWork;
|
||||
|
||||
// Keep track of this so we can reset the priority context if an error
|
||||
// is thrown during reconciliation.
|
||||
|
@ -686,6 +682,8 @@ module.exports = function<T, P, I, TI, PI, C, CX, PL>(
|
|||
}
|
||||
|
||||
// Without this explicit null return Flow complains of invalid return type
|
||||
// TODO Remove the above while(true) loop
|
||||
// eslint-disable-next-line no-unreachable
|
||||
return null;
|
||||
}
|
||||
|
||||
|
@ -1146,17 +1144,21 @@ module.exports = function<T, P, I, TI, PI, C, CX, PL>(
|
|||
function hasCapturedError(fiber: Fiber): boolean {
|
||||
// TODO: capturedErrors should store the boundary instance, to avoid needing
|
||||
// to check the alternate.
|
||||
return capturedErrors !== null &&
|
||||
return (
|
||||
capturedErrors !== null &&
|
||||
(capturedErrors.has(fiber) ||
|
||||
(fiber.alternate !== null && capturedErrors.has(fiber.alternate)));
|
||||
(fiber.alternate !== null && capturedErrors.has(fiber.alternate)))
|
||||
);
|
||||
}
|
||||
|
||||
function isFailedBoundary(fiber: Fiber): boolean {
|
||||
// TODO: failedBoundaries should store the boundary instance, to avoid
|
||||
// needing to check the alternate.
|
||||
return failedBoundaries !== null &&
|
||||
return (
|
||||
failedBoundaries !== null &&
|
||||
(failedBoundaries.has(fiber) ||
|
||||
(fiber.alternate !== null && failedBoundaries.has(fiber.alternate)));
|
||||
(fiber.alternate !== null && failedBoundaries.has(fiber.alternate)))
|
||||
);
|
||||
}
|
||||
|
||||
function commitErrorHandling(effectfulFiber: Fiber) {
|
||||
|
@ -1340,16 +1342,32 @@ module.exports = function<T, P, I, TI, PI, C, CX, PL>(
|
|||
}
|
||||
}
|
||||
|
||||
function getPriorityContext(): PriorityLevel {
|
||||
function getPriorityContext(
|
||||
fiber: Fiber,
|
||||
forceAsync: boolean,
|
||||
): PriorityLevel {
|
||||
let priorityLevel = priorityContext;
|
||||
if (priorityLevel === NoWork) {
|
||||
if (
|
||||
!useSyncScheduling ||
|
||||
fiber.internalContextTag & AsyncUpdates ||
|
||||
forceAsync
|
||||
) {
|
||||
priorityLevel = LowPriority;
|
||||
} else {
|
||||
priorityLevel = SynchronousPriority;
|
||||
}
|
||||
}
|
||||
|
||||
// If we're in a batch, or if we're already performing work, downgrade sync
|
||||
// priority to task priority
|
||||
if (
|
||||
priorityContext === SynchronousPriority &&
|
||||
priorityLevel === SynchronousPriority &&
|
||||
(isPerformingWork || isBatchingUpdates)
|
||||
) {
|
||||
return TaskPriority;
|
||||
}
|
||||
return priorityContext;
|
||||
return priorityLevel;
|
||||
}
|
||||
|
||||
function scheduleErrorRecovery(fiber: Fiber) {
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
import type {Fiber} from 'ReactFiber';
|
||||
|
||||
var ReactInstanceMap = require('ReactInstanceMap');
|
||||
var ReactCurrentOwner = require('react/lib/ReactCurrentOwner');
|
||||
var {ReactCurrentOwner} = require('ReactGlobalSharedState');
|
||||
|
||||
var getComponentName = require('getComponentName');
|
||||
var invariant = require('fbjs/lib/invariant');
|
||||
|
@ -31,10 +31,7 @@ var {
|
|||
ClassComponent,
|
||||
} = require('ReactTypeOfWork');
|
||||
|
||||
var {
|
||||
NoEffect,
|
||||
Placement,
|
||||
} = require('ReactTypeOfSideEffect');
|
||||
var {NoEffect, Placement} = require('ReactTypeOfSideEffect');
|
||||
|
||||
var MOUNTING = 1;
|
||||
var MOUNTED = 2;
|
||||
|
|
|
@ -15,9 +15,7 @@
|
|||
import type {Fiber} from 'ReactFiber';
|
||||
import type {PriorityLevel} from 'ReactPriorityLevel';
|
||||
|
||||
const {
|
||||
Callback: CallbackEffect,
|
||||
} = require('ReactTypeOfSideEffect');
|
||||
const {Callback: CallbackEffect} = require('ReactTypeOfSideEffect');
|
||||
|
||||
const {
|
||||
NoWork,
|
||||
|
@ -431,7 +429,8 @@ function beginUpdateQueue(
|
|||
let callbackList = null;
|
||||
let update = queue.first;
|
||||
while (
|
||||
update !== null && comparePriority(update.priorityLevel, priorityLevel) <= 0
|
||||
update !== null &&
|
||||
comparePriority(update.priorityLevel, priorityLevel) <= 0
|
||||
) {
|
||||
// Remove each update from the queue right before it is processed. That way
|
||||
// if setState is called from inside an updater function, the new update
|
||||
|
|
|
@ -0,0 +1,20 @@
|
|||
/**
|
||||
* Copyright 2013-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 ReactTypeOfInternalContext
|
||||
* @flow
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
export type TypeOfInternalContext = number;
|
||||
|
||||
module.exports = {
|
||||
NoContext: 0,
|
||||
AsyncUpdates: 1,
|
||||
};
|
|
@ -12,16 +12,16 @@
|
|||
|
||||
'use strict';
|
||||
|
||||
export type TypeOfSideEffect = 0 | 1 | 2 | 3 | 4 | 8 | 16 | 32 | 64;
|
||||
export type TypeOfSideEffect = number;
|
||||
|
||||
module.exports = {
|
||||
NoEffect: 0, // 0b0000000
|
||||
Placement: 1, // 0b0000001
|
||||
Update: 2, // 0b0000010
|
||||
NoEffect: 0, // 0b0000000
|
||||
Placement: 1, // 0b0000001
|
||||
Update: 2, // 0b0000010
|
||||
PlacementAndUpdate: 3, // 0b0000011
|
||||
Deletion: 4, // 0b0000100
|
||||
ContentReset: 8, // 0b0001000
|
||||
Callback: 16, // 0b0010000
|
||||
Err: 32, // 0b0100000
|
||||
Ref: 64, // 0b1000000
|
||||
Deletion: 4, // 0b0000100
|
||||
ContentReset: 8, // 0b0001000
|
||||
Callback: 16, // 0b0010000
|
||||
Err: 32, // 0b0100000
|
||||
Ref: 64, // 0b1000000
|
||||
};
|
||||
|
|
|
@ -27,7 +27,7 @@ describe('ReactCoroutine', () => {
|
|||
});
|
||||
|
||||
function div(...children) {
|
||||
children = children.map(c => typeof c === 'string' ? {text: c} : c);
|
||||
children = children.map(c => (typeof c === 'string' ? {text: c} : c));
|
||||
return {type: 'div', children, prop: undefined};
|
||||
}
|
||||
|
||||
|
@ -57,13 +57,13 @@ describe('ReactCoroutine', () => {
|
|||
|
||||
function Indirection() {
|
||||
ops.push('Indirection');
|
||||
return [<Child bar={true} />, <Child bar={false} />];
|
||||
return [<Child key="a" bar={true} />, <Child key="b" bar={false} />];
|
||||
}
|
||||
|
||||
function HandleYields(props, yields) {
|
||||
ops.push('HandleYields');
|
||||
return yields.map(y => (
|
||||
<y.continuation isSame={props.foo === y.props.bar} />
|
||||
return yields.map((y, i) => (
|
||||
<y.continuation key={i} isSame={props.foo === y.props.bar} />
|
||||
));
|
||||
}
|
||||
|
||||
|
@ -117,12 +117,12 @@ describe('ReactCoroutine', () => {
|
|||
}
|
||||
|
||||
function Indirection() {
|
||||
return [<Child bar={true} />, <Child bar={false} />];
|
||||
return [<Child key="a" bar={true} />, <Child key="b" bar={false} />];
|
||||
}
|
||||
|
||||
function HandleYields(props, yields) {
|
||||
return yields.map(y => (
|
||||
<y.continuation isSame={props.foo === y.props.bar} />
|
||||
return yields.map((y, i) => (
|
||||
<y.continuation key={i} isSame={props.foo === y.props.bar} />
|
||||
));
|
||||
}
|
||||
|
||||
|
@ -176,7 +176,9 @@ describe('ReactCoroutine', () => {
|
|||
|
||||
function HandleYields(props, yields) {
|
||||
ops.push('HandleYields');
|
||||
return yields.map(ContinuationComponent => <ContinuationComponent />);
|
||||
return yields.map((ContinuationComponent, i) => (
|
||||
<ContinuationComponent key={i} />
|
||||
));
|
||||
}
|
||||
|
||||
class Parent extends React.Component {
|
||||
|
@ -223,8 +225,12 @@ describe('ReactCoroutine', () => {
|
|||
|
||||
function App(props) {
|
||||
return ReactCoroutine.createCoroutine(
|
||||
[<Counter id="a" />, <Counter id="b" />, <Counter id="c" />],
|
||||
(p, yields) => yields.map(y => <span prop={y * 100} />),
|
||||
[
|
||||
<Counter key="a" id="a" />,
|
||||
<Counter key="b" id="b" />,
|
||||
<Counter key="c" id="c" />,
|
||||
],
|
||||
(p, yields) => yields.map((y, i) => <span key={i} prop={y * 100} />),
|
||||
{},
|
||||
);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,62 @@
|
|||
/**
|
||||
* Copyright 2013-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.
|
||||
*
|
||||
* @emails react-core
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
var React;
|
||||
var ReactFiberReconciler;
|
||||
|
||||
describe('ReactFiberHostContext', () => {
|
||||
beforeEach(() => {
|
||||
jest.resetModules();
|
||||
React = require('React');
|
||||
ReactFiberReconciler = require('ReactFiberReconciler');
|
||||
});
|
||||
|
||||
it('works with null host context', () => {
|
||||
var creates = 0;
|
||||
var Renderer = ReactFiberReconciler({
|
||||
prepareForCommit: function() {},
|
||||
resetAfterCommit: function() {},
|
||||
getRootHostContext: function() {
|
||||
return null;
|
||||
},
|
||||
getChildHostContext: function() {
|
||||
return null;
|
||||
},
|
||||
shouldSetTextContent: function() {
|
||||
return false;
|
||||
},
|
||||
createInstance: function() {
|
||||
creates++;
|
||||
},
|
||||
finalizeInitialChildren: function() {
|
||||
return null;
|
||||
},
|
||||
appendInitialChild: function() {
|
||||
return null;
|
||||
},
|
||||
appendChild: function() {
|
||||
return null;
|
||||
},
|
||||
useSyncScheduling: true,
|
||||
});
|
||||
|
||||
const container = Renderer.createContainer(/* root: */ null);
|
||||
Renderer.updateContainer(
|
||||
<a><b /></a>,
|
||||
container,
|
||||
/* parentComponent: */ null,
|
||||
/* callback: */ null,
|
||||
);
|
||||
expect(creates).toBe(2);
|
||||
});
|
||||
});
|
|
@ -11,17 +11,17 @@
|
|||
|
||||
'use strict';
|
||||
|
||||
var PropTypes;
|
||||
var React;
|
||||
var ReactNoop;
|
||||
var ReactFeatureFlags;
|
||||
var PropTypes;
|
||||
|
||||
describe('ReactIncremental', () => {
|
||||
beforeEach(() => {
|
||||
jest.resetModules();
|
||||
PropTypes = require('prop-types');
|
||||
React = require('react');
|
||||
ReactNoop = require('ReactNoop');
|
||||
PropTypes = require('prop-types');
|
||||
|
||||
ReactFeatureFlags = require('ReactFeatureFlags');
|
||||
ReactFeatureFlags.disableNewFiberFeatures = false;
|
||||
|
@ -51,10 +51,10 @@ describe('ReactIncremental', () => {
|
|||
var fooCalled = false;
|
||||
function Foo() {
|
||||
fooCalled = true;
|
||||
return [<Bar isBar={true} />, <Bar isBar={true} />];
|
||||
return [<Bar key="a" isBar={true} />, <Bar key="b" isBar={true} />];
|
||||
}
|
||||
|
||||
ReactNoop.render(<Foo />, () => renderCallbackCalled = true);
|
||||
ReactNoop.render(<Foo />, () => (renderCallbackCalled = true));
|
||||
expect(fooCalled).toBe(false);
|
||||
expect(barCalled).toBe(false);
|
||||
expect(renderCallbackCalled).toBe(false);
|
||||
|
@ -103,7 +103,8 @@ describe('ReactIncremental', () => {
|
|||
}
|
||||
|
||||
ReactNoop.render(<Foo text="foo" />, () =>
|
||||
ops.push('renderCallbackCalled'));
|
||||
ops.push('renderCallbackCalled'),
|
||||
);
|
||||
ReactNoop.flush();
|
||||
|
||||
expect(ops).toEqual([
|
||||
|
@ -117,9 +118,11 @@ describe('ReactIncremental', () => {
|
|||
ops = [];
|
||||
|
||||
ReactNoop.render(<Foo text="bar" />, () =>
|
||||
ops.push('firstRenderCallbackCalled'));
|
||||
ops.push('firstRenderCallbackCalled'),
|
||||
);
|
||||
ReactNoop.render(<Foo text="bar" />, () =>
|
||||
ops.push('secondRenderCallbackCalled'));
|
||||
ops.push('secondRenderCallbackCalled'),
|
||||
);
|
||||
ReactNoop.flush();
|
||||
|
||||
// TODO: Test bail out of host components. This is currently unobservable.
|
||||
|
@ -384,8 +387,8 @@ describe('ReactIncremental', () => {
|
|||
}
|
||||
render() {
|
||||
return [
|
||||
<Tester unused={this.props.unused} />,
|
||||
<bbb hidden={true}>
|
||||
<Tester key="a" unused={this.props.unused} />,
|
||||
<bbb key="b" hidden={true}>
|
||||
<ccc>
|
||||
<Middle>Hi</Middle>
|
||||
</ccc>
|
||||
|
@ -449,6 +452,47 @@ describe('ReactIncremental', () => {
|
|||
expect(ops).toEqual(['Foo', 'Bar', 'Bar']);
|
||||
});
|
||||
|
||||
it('can resume mounting a class component', () => {
|
||||
let ops = [];
|
||||
let foo;
|
||||
class Parent extends React.Component {
|
||||
shouldComponentUpdate() {
|
||||
return false;
|
||||
}
|
||||
render() {
|
||||
return <Foo prop={this.props.prop} />;
|
||||
}
|
||||
}
|
||||
|
||||
class Foo extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
// Test based on a www bug where props was null on resume
|
||||
ops.push('Foo constructor: ' + props.prop);
|
||||
}
|
||||
render() {
|
||||
foo = this;
|
||||
ops.push('Foo');
|
||||
return <Bar />;
|
||||
}
|
||||
}
|
||||
|
||||
function Bar() {
|
||||
ops.push('Bar');
|
||||
return <div />;
|
||||
}
|
||||
|
||||
ReactNoop.render(<Parent prop="foo" />);
|
||||
ReactNoop.flushDeferredPri(20);
|
||||
expect(ops).toEqual(['Foo constructor: foo', 'Foo']);
|
||||
|
||||
foo.setState({value: 'bar'});
|
||||
|
||||
ops = [];
|
||||
ReactNoop.flush();
|
||||
expect(ops).toEqual(['Foo constructor: foo', 'Foo', 'Bar']);
|
||||
});
|
||||
|
||||
it('can reuse work done after being preempted', () => {
|
||||
var ops = [];
|
||||
|
||||
|
@ -583,8 +627,8 @@ describe('ReactIncremental', () => {
|
|||
// low priority. I think this would be fixed by changing
|
||||
// pendingWorkPriority and progressedPriority to be the priority of
|
||||
// the children only, not including the fiber itself.
|
||||
<div><Child /></div>,
|
||||
<Sibling />,
|
||||
<div key="a"><Child /></div>,
|
||||
<Sibling key="b" />,
|
||||
];
|
||||
}
|
||||
|
||||
|
@ -875,15 +919,13 @@ describe('ReactIncremental', () => {
|
|||
|
||||
it('can replaceState', () => {
|
||||
let instance;
|
||||
const Bar = React.createClass({
|
||||
getInitialState() {
|
||||
instance = this;
|
||||
return {a: 'a'};
|
||||
},
|
||||
class Bar extends React.Component {
|
||||
state = {a: 'a'};
|
||||
render() {
|
||||
instance = this;
|
||||
return <div>{this.props.children}</div>;
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function Foo() {
|
||||
return (
|
||||
|
@ -897,7 +939,7 @@ describe('ReactIncremental', () => {
|
|||
ReactNoop.flush();
|
||||
instance.setState({b: 'b'});
|
||||
instance.setState({c: 'c'});
|
||||
instance.replaceState({d: 'd'});
|
||||
instance.updater.enqueueReplaceState(instance, {d: 'd'});
|
||||
ReactNoop.flush();
|
||||
expect(instance.state).toEqual({d: 'd'});
|
||||
});
|
||||
|
@ -1415,7 +1457,7 @@ describe('ReactIncremental', () => {
|
|||
}
|
||||
|
||||
function App(props) {
|
||||
return [<LifeCycle x={props.x} />, <Sibling />];
|
||||
return [<LifeCycle key="a" x={props.x} />, <Sibling key="b" />];
|
||||
}
|
||||
|
||||
ReactNoop.render(<App x={0} />);
|
||||
|
@ -1664,13 +1706,13 @@ describe('ReactIncremental', () => {
|
|||
render() {
|
||||
ops.push('Indirection ' + JSON.stringify(this.context));
|
||||
return [
|
||||
<ShowLocale />,
|
||||
<ShowRoute />,
|
||||
<ShowNeither />,
|
||||
<Intl locale="ru">
|
||||
<ShowLocale key="a" />,
|
||||
<ShowRoute key="b" />,
|
||||
<ShowNeither key="c" />,
|
||||
<Intl key="d" locale="ru">
|
||||
<ShowBoth />
|
||||
</Intl>,
|
||||
<ShowBoth />,
|
||||
<ShowBoth key="e" />,
|
||||
];
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
|
||||
'use strict';
|
||||
|
||||
var PropTypes;
|
||||
var React;
|
||||
var ReactNoop;
|
||||
var ReactFeatureFlags;
|
||||
|
@ -18,6 +19,7 @@ var ReactFeatureFlags;
|
|||
describe('ReactIncrementalErrorHandling', () => {
|
||||
beforeEach(() => {
|
||||
jest.resetModules();
|
||||
PropTypes = require('prop-types');
|
||||
React = require('react');
|
||||
ReactNoop = require('ReactNoop');
|
||||
ReactFeatureFlags = require('ReactFeatureFlags');
|
||||
|
@ -25,7 +27,7 @@ describe('ReactIncrementalErrorHandling', () => {
|
|||
});
|
||||
|
||||
function div(...children) {
|
||||
children = children.map(c => typeof c === 'string' ? {text: c} : c);
|
||||
children = children.map(c => (typeof c === 'string' ? {text: c} : c));
|
||||
return {type: 'div', children, prop: undefined};
|
||||
}
|
||||
|
||||
|
|
|
@ -12,12 +12,12 @@
|
|||
'use strict';
|
||||
|
||||
describe('ReactDebugFiberPerf', () => {
|
||||
let PropTypes;
|
||||
let React;
|
||||
let ReactCoroutine;
|
||||
let ReactFeatureFlags;
|
||||
let ReactNoop;
|
||||
let ReactPortal;
|
||||
let PropTypes;
|
||||
|
||||
let root;
|
||||
let activeMeasure;
|
||||
|
@ -71,12 +71,14 @@ describe('ReactDebugFiberPerf', () => {
|
|||
label: null,
|
||||
parent: activeMeasure,
|
||||
toString() {
|
||||
return [
|
||||
' '.repeat(this.indent) + this.label,
|
||||
...this.children.map(c => c.toString()),
|
||||
].join('\n') +
|
||||
return (
|
||||
[
|
||||
' '.repeat(this.indent) + this.label,
|
||||
...this.children.map(c => c.toString()),
|
||||
].join('\n') +
|
||||
// Extra newline after each root reconciliation
|
||||
(this.indent === 0 ? '\n' : '');
|
||||
(this.indent === 0 ? '\n' : '')
|
||||
);
|
||||
},
|
||||
};
|
||||
// Step one level deeper
|
||||
|
@ -114,13 +116,13 @@ describe('ReactDebugFiberPerf', () => {
|
|||
global.performance = createUserTimingPolyfill();
|
||||
|
||||
// Import after the polyfill is set up:
|
||||
PropTypes = require('prop-types');
|
||||
React = require('React');
|
||||
ReactCoroutine = require('ReactCoroutine');
|
||||
ReactFeatureFlags = require('ReactFeatureFlags');
|
||||
ReactNoop = require('ReactNoop');
|
||||
ReactPortal = require('ReactPortal');
|
||||
ReactFeatureFlags.disableNewFiberFeatures = false;
|
||||
PropTypes = require('prop-types');
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
|
@ -170,11 +172,11 @@ describe('ReactDebugFiberPerf', () => {
|
|||
<Parent>
|
||||
<Parent>
|
||||
<Parent>
|
||||
<A ref={inst => a = inst} />
|
||||
<A ref={inst => (a = inst)} />
|
||||
</Parent>
|
||||
</Parent>
|
||||
<Parent>
|
||||
<B ref={inst => b = inst} />
|
||||
<B ref={inst => (b = inst)} />
|
||||
</Parent>
|
||||
</Parent>,
|
||||
);
|
||||
|
@ -449,12 +451,12 @@ describe('ReactDebugFiberPerf', () => {
|
|||
}
|
||||
|
||||
function Indirection() {
|
||||
return [<CoChild bar={true} />, <CoChild bar={false} />];
|
||||
return [<CoChild key="a" bar={true} />, <CoChild key="b" bar={false} />];
|
||||
}
|
||||
|
||||
function HandleYields(props, yields) {
|
||||
return yields.map(y => (
|
||||
<y.continuation isSame={props.foo === y.props.bar} />
|
||||
return yields.map((y, i) => (
|
||||
<y.continuation key={i} isSame={props.foo === y.props.bar} />
|
||||
));
|
||||
}
|
||||
|
||||
|
|
|
@ -29,18 +29,23 @@ describe('ReactIncrementalReflection', () => {
|
|||
|
||||
const instances = [];
|
||||
|
||||
const Component = React.createClass({
|
||||
class Component extends React.Component {
|
||||
_isMounted() {
|
||||
// No longer a public API, but we can test that it works internally by
|
||||
// reaching into the updater.
|
||||
return this.updater.isMounted(this);
|
||||
}
|
||||
componentWillMount() {
|
||||
instances.push(this);
|
||||
ops.push('componentWillMount', this.isMounted());
|
||||
},
|
||||
ops.push('componentWillMount', this._isMounted());
|
||||
}
|
||||
componentDidMount() {
|
||||
ops.push('componentDidMount', this.isMounted());
|
||||
},
|
||||
ops.push('componentDidMount', this._isMounted());
|
||||
}
|
||||
render() {
|
||||
return <span />;
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function Foo() {
|
||||
return <Component />;
|
||||
|
@ -53,7 +58,7 @@ describe('ReactIncrementalReflection', () => {
|
|||
|
||||
expect(ops).toEqual(['componentWillMount', false]);
|
||||
|
||||
expect(instances[0].isMounted()).toBe(false);
|
||||
expect(instances[0]._isMounted()).toBe(false);
|
||||
|
||||
ops = [];
|
||||
|
||||
|
@ -62,7 +67,7 @@ describe('ReactIncrementalReflection', () => {
|
|||
|
||||
expect(ops).toEqual(['componentDidMount', true]);
|
||||
|
||||
expect(instances[0].isMounted()).toBe(true);
|
||||
expect(instances[0]._isMounted()).toBe(true);
|
||||
});
|
||||
|
||||
it('handles isMounted when an unmount is deferred', () => {
|
||||
|
@ -70,18 +75,21 @@ describe('ReactIncrementalReflection', () => {
|
|||
|
||||
const instances = [];
|
||||
|
||||
const Component = React.createClass({
|
||||
class Component extends React.Component {
|
||||
_isMounted() {
|
||||
return this.updater.isMounted(this);
|
||||
}
|
||||
componentWillMount() {
|
||||
instances.push(this);
|
||||
},
|
||||
}
|
||||
componentWillUnmount() {
|
||||
ops.push('componentWillUnmount', this.isMounted());
|
||||
},
|
||||
ops.push('componentWillUnmount', this._isMounted());
|
||||
}
|
||||
render() {
|
||||
ops.push('Component');
|
||||
return <span />;
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function Other() {
|
||||
ops.push('Other');
|
||||
|
@ -98,7 +106,7 @@ describe('ReactIncrementalReflection', () => {
|
|||
expect(ops).toEqual(['Component']);
|
||||
ops = [];
|
||||
|
||||
expect(instances[0].isMounted()).toBe(true);
|
||||
expect(instances[0]._isMounted()).toBe(true);
|
||||
|
||||
ReactNoop.render(<Foo mount={false} />);
|
||||
// Render part way through but don't yet commit the updates so it is not
|
||||
|
@ -108,14 +116,14 @@ describe('ReactIncrementalReflection', () => {
|
|||
expect(ops).toEqual(['Other']);
|
||||
ops = [];
|
||||
|
||||
expect(instances[0].isMounted()).toBe(true);
|
||||
expect(instances[0]._isMounted()).toBe(true);
|
||||
|
||||
// Finish flushing the unmount.
|
||||
ReactNoop.flush();
|
||||
|
||||
expect(ops).toEqual(['componentWillUnmount', true]);
|
||||
|
||||
expect(instances[0].isMounted()).toBe(false);
|
||||
expect(instances[0]._isMounted()).toBe(false);
|
||||
});
|
||||
|
||||
it('finds no node before insertion and correct node before deletion', () => {
|
||||
|
@ -143,13 +151,13 @@ describe('ReactIncrementalReflection', () => {
|
|||
render() {
|
||||
ops.push('render');
|
||||
return this.props.step < 2
|
||||
? <span ref={ref => this.span = ref} />
|
||||
? <span ref={ref => (this.span = ref)} />
|
||||
: this.props.step === 2
|
||||
? <div ref={ref => this.div = ref} />
|
||||
? <div ref={ref => (this.div = ref)} />
|
||||
: this.props.step === 3
|
||||
? null
|
||||
: this.props.step === 4
|
||||
? <div ref={ref => this.span = ref} />
|
||||
? <div ref={ref => (this.span = ref)} />
|
||||
: null;
|
||||
}
|
||||
}
|
||||
|
@ -161,7 +169,7 @@ describe('ReactIncrementalReflection', () => {
|
|||
}
|
||||
|
||||
function Foo(props) {
|
||||
return [<Component step={props.step} />, <Sibling />];
|
||||
return [<Component key="a" step={props.step} />, <Sibling key="b" />];
|
||||
}
|
||||
|
||||
ReactNoop.render(<Foo step={0} />);
|
||||
|
|
|
@ -29,7 +29,7 @@ describe('ReactIncrementalSideEffects', () => {
|
|||
}
|
||||
|
||||
function div(...children) {
|
||||
children = children.map(c => typeof c === 'string' ? {text: c} : c);
|
||||
children = children.map(c => (typeof c === 'string' ? {text: c} : c));
|
||||
return {type: 'div', children, prop: undefined};
|
||||
}
|
||||
|
||||
|
@ -565,7 +565,10 @@ describe('ReactIncrementalSideEffects', () => {
|
|||
}
|
||||
render() {
|
||||
ops.push('Baz');
|
||||
return [<Bar idx={this.props.idx} />, <Bar idx={this.props.idx} />];
|
||||
return [
|
||||
<Bar key="a" idx={this.props.idx} />,
|
||||
<Bar key="b" idx={this.props.idx} />,
|
||||
];
|
||||
}
|
||||
}
|
||||
function Foo(props) {
|
||||
|
|
|
@ -74,22 +74,20 @@ describe('ReactIncrementalUpdates', () => {
|
|||
it('only drops updates with equal or lesser priority when replaceState is called', () => {
|
||||
let instance;
|
||||
let ops = [];
|
||||
const Foo = React.createClass({
|
||||
getInitialState() {
|
||||
return {};
|
||||
},
|
||||
class Foo extends React.Component {
|
||||
state = {};
|
||||
componentDidMount() {
|
||||
ops.push('componentDidMount');
|
||||
},
|
||||
}
|
||||
componentDidUpdate() {
|
||||
ops.push('componentDidUpdate');
|
||||
},
|
||||
}
|
||||
render() {
|
||||
ops.push('render');
|
||||
instance = this;
|
||||
return <div />;
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
ReactNoop.render(<Foo />);
|
||||
ReactNoop.flush();
|
||||
|
@ -100,7 +98,7 @@ describe('ReactIncrementalUpdates', () => {
|
|||
instance.setState({a: 'a'});
|
||||
instance.setState({b: 'b'});
|
||||
});
|
||||
instance.replaceState({c: 'c'});
|
||||
instance.updater.enqueueReplaceState(instance, {c: 'c'});
|
||||
instance.setState({d: 'd'});
|
||||
|
||||
ReactNoop.flushAnimationPri();
|
||||
|
@ -201,19 +199,17 @@ describe('ReactIncrementalUpdates', () => {
|
|||
it('can abort an update, schedule a replaceState, and resume', () => {
|
||||
let instance;
|
||||
let ops = [];
|
||||
const Foo = React.createClass({
|
||||
getInitialState() {
|
||||
return {};
|
||||
},
|
||||
class Foo extends React.Component {
|
||||
state = {};
|
||||
componentDidUpdate() {
|
||||
ops.push('componentDidUpdate');
|
||||
},
|
||||
}
|
||||
render() {
|
||||
ops.push('render');
|
||||
instance = this;
|
||||
return <span />;
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
ReactNoop.render(<Foo />);
|
||||
ReactNoop.flush();
|
||||
|
@ -245,7 +241,9 @@ describe('ReactIncrementalUpdates', () => {
|
|||
instance.setState(createUpdate('f'));
|
||||
ReactNoop.performAnimationWork(() => {
|
||||
instance.setState(createUpdate('d'));
|
||||
instance.replaceState(createUpdate('e'));
|
||||
// No longer a public API, but we can test that it works internally by
|
||||
// reaching into the updater.
|
||||
instance.updater.enqueueReplaceState(instance, createUpdate('e'));
|
||||
});
|
||||
instance.setState(createUpdate('g'));
|
||||
|
||||
|
@ -256,21 +254,23 @@ describe('ReactIncrementalUpdates', () => {
|
|||
|
||||
it('passes accumulation of previous updates to replaceState updater function', () => {
|
||||
let instance;
|
||||
const Foo = React.createClass({
|
||||
getInitialState() {
|
||||
return {};
|
||||
},
|
||||
class Foo extends React.Component {
|
||||
state = {};
|
||||
render() {
|
||||
instance = this;
|
||||
return <span />;
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
ReactNoop.render(<Foo />);
|
||||
ReactNoop.flush();
|
||||
|
||||
instance.setState({a: 'a'});
|
||||
instance.setState({b: 'b'});
|
||||
instance.replaceState(previousState => ({previousState}));
|
||||
// No longer a public API, but we can test that it works internally by
|
||||
// reaching into the updater.
|
||||
instance.updater.enqueueReplaceState(instance, previousState => ({
|
||||
previousState,
|
||||
}));
|
||||
ReactNoop.flush();
|
||||
expect(instance.state).toEqual({previousState: {a: 'a', b: 'b'}});
|
||||
});
|
||||
|
|
|
@ -77,7 +77,7 @@ describe('ReactTopLevelFragment', function() {
|
|||
function Fragment({condition}) {
|
||||
return condition
|
||||
? <Stateful key="a" />
|
||||
: [[<Stateful key="a" />, <div key="b">World</div>], <div />];
|
||||
: [[<Stateful key="a" />, <div key="b">World</div>], <div key="c" />];
|
||||
}
|
||||
ReactNoop.render(<Fragment />);
|
||||
ReactNoop.flush();
|
||||
|
@ -106,8 +106,8 @@ describe('ReactTopLevelFragment', function() {
|
|||
|
||||
function Fragment({condition}) {
|
||||
return condition
|
||||
? [null, <Stateful />]
|
||||
: [<div>Hello</div>, <Stateful />];
|
||||
? [null, <Stateful key="a" />]
|
||||
: [<div key="b">Hello</div>, <Stateful key="a" />];
|
||||
}
|
||||
ReactNoop.render(<Fragment />);
|
||||
ReactNoop.flush();
|
||||
|
@ -144,7 +144,7 @@ describe('ReactTopLevelFragment', function() {
|
|||
function Fragment({condition}) {
|
||||
return condition
|
||||
? [[<div key="b">World</div>, <Stateful key="a" />]]
|
||||
: [[<Stateful key="a" />, <div key="b">World</div>], <div />];
|
||||
: [[<Stateful key="a" />, <div key="b">World</div>], <div key="c" />];
|
||||
}
|
||||
ReactNoop.render(<Fragment />);
|
||||
ReactNoop.flush();
|
||||
|
|
|
@ -88,18 +88,22 @@ exports.createYield = function(value: mixed): ReactYield {
|
|||
* Verifies the object is a coroutine object.
|
||||
*/
|
||||
exports.isCoroutine = function(object: mixed): boolean {
|
||||
return typeof object === 'object' &&
|
||||
return (
|
||||
typeof object === 'object' &&
|
||||
object !== null &&
|
||||
object.$$typeof === REACT_COROUTINE_TYPE;
|
||||
object.$$typeof === REACT_COROUTINE_TYPE
|
||||
);
|
||||
};
|
||||
|
||||
/**
|
||||
* Verifies the object is a yield object.
|
||||
*/
|
||||
exports.isYield = function(object: mixed): boolean {
|
||||
return typeof object === 'object' &&
|
||||
return (
|
||||
typeof object === 'object' &&
|
||||
object !== null &&
|
||||
object.$$typeof === REACT_YIELD_TYPE;
|
||||
object.$$typeof === REACT_YIELD_TYPE
|
||||
);
|
||||
};
|
||||
|
||||
exports.REACT_YIELD_TYPE = REACT_YIELD_TYPE;
|
||||
|
|
|
@ -16,9 +16,8 @@ import type {ReactNodeList} from 'ReactTypes';
|
|||
|
||||
// The Symbol used to tag the special React types. If there is no native Symbol
|
||||
// nor polyfill, then a plain number is used for performance.
|
||||
var REACT_PORTAL_TYPE = (typeof Symbol === 'function' &&
|
||||
Symbol.for &&
|
||||
Symbol.for('react.portal')) ||
|
||||
var REACT_PORTAL_TYPE =
|
||||
(typeof Symbol === 'function' && Symbol.for && Symbol.for('react.portal')) ||
|
||||
0xeaca;
|
||||
|
||||
export type ReactPortal = {
|
||||
|
@ -51,9 +50,11 @@ exports.createPortal = function(
|
|||
* Verifies the object is a portal object.
|
||||
*/
|
||||
exports.isPortal = function(object: mixed): boolean {
|
||||
return typeof object === 'object' &&
|
||||
return (
|
||||
typeof object === 'object' &&
|
||||
object !== null &&
|
||||
object.$$typeof === REACT_PORTAL_TYPE;
|
||||
object.$$typeof === REACT_PORTAL_TYPE
|
||||
);
|
||||
};
|
||||
|
||||
exports.REACT_PORTAL_TYPE = REACT_PORTAL_TYPE;
|
||||
|
|
|
@ -14,18 +14,16 @@
|
|||
|
||||
import type {DebugID} from 'ReactInstanceType';
|
||||
|
||||
export type Operation =
|
||||
& {instanceID: DebugID}
|
||||
& (
|
||||
| {type: 'mount', payload: string}
|
||||
| {type: 'insert child', payload: {toIndex: number, content: string}}
|
||||
| {type: 'move child', payload: {fromIndex: number, toIndex: number}}
|
||||
| {type: 'replace children', payload: string}
|
||||
| {type: 'replace text', payload: string}
|
||||
| {type: 'replace with', payload: string}
|
||||
| {type: 'update styles', payload: mixed /* Style Object */}
|
||||
| {type: 'update attribute', payload: {[name: string]: string}}
|
||||
| {type: 'remove attribute', payload: string});
|
||||
export type Operation = {instanceID: DebugID} & (
|
||||
| {type: 'mount', payload: string}
|
||||
| {type: 'insert child', payload: {toIndex: number, content: string}}
|
||||
| {type: 'move child', payload: {fromIndex: number, toIndex: number}}
|
||||
| {type: 'replace children', payload: string}
|
||||
| {type: 'replace text', payload: string}
|
||||
| {type: 'replace with', payload: string}
|
||||
| {type: 'update styles', payload: mixed /* Style Object */}
|
||||
| {type: 'update attribute', payload: {[name: string]: string}}
|
||||
| {type: 'remove attribute', payload: string});
|
||||
|
||||
// Trust the developer to only use this with a __DEV__ check
|
||||
var ReactHostOperationHistoryHook = ((null: any): typeof ReactHostOperationHistoryHook);
|
||||
|
|
|
@ -0,0 +1,103 @@
|
|||
/**
|
||||
* Copyright 2013-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 BrowserEventConstants
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
var getVendorPrefixedEventName = require('getVendorPrefixedEventName');
|
||||
|
||||
/**
|
||||
* Types of raw signals from the browser caught at the top level.
|
||||
*
|
||||
* For events like 'submit' which don't consistently bubble (which we
|
||||
* trap at a lower node than `document`), binding at `document` would
|
||||
* cause duplicate events so we don't include them here.
|
||||
*/
|
||||
var topLevelTypes = {
|
||||
topAbort: 'abort',
|
||||
topAnimationEnd: getVendorPrefixedEventName('animationend') || 'animationend',
|
||||
topAnimationIteration: getVendorPrefixedEventName('animationiteration') ||
|
||||
'animationiteration',
|
||||
topAnimationStart: getVendorPrefixedEventName('animationstart') ||
|
||||
'animationstart',
|
||||
topBlur: 'blur',
|
||||
topCancel: 'cancel',
|
||||
topCanPlay: 'canplay',
|
||||
topCanPlayThrough: 'canplaythrough',
|
||||
topChange: 'change',
|
||||
topClick: 'click',
|
||||
topClose: 'close',
|
||||
topCompositionEnd: 'compositionend',
|
||||
topCompositionStart: 'compositionstart',
|
||||
topCompositionUpdate: 'compositionupdate',
|
||||
topContextMenu: 'contextmenu',
|
||||
topCopy: 'copy',
|
||||
topCut: 'cut',
|
||||
topDoubleClick: 'dblclick',
|
||||
topDrag: 'drag',
|
||||
topDragEnd: 'dragend',
|
||||
topDragEnter: 'dragenter',
|
||||
topDragExit: 'dragexit',
|
||||
topDragLeave: 'dragleave',
|
||||
topDragOver: 'dragover',
|
||||
topDragStart: 'dragstart',
|
||||
topDrop: 'drop',
|
||||
topDurationChange: 'durationchange',
|
||||
topEmptied: 'emptied',
|
||||
topEncrypted: 'encrypted',
|
||||
topEnded: 'ended',
|
||||
topError: 'error',
|
||||
topFocus: 'focus',
|
||||
topInput: 'input',
|
||||
topKeyDown: 'keydown',
|
||||
topKeyPress: 'keypress',
|
||||
topKeyUp: 'keyup',
|
||||
topLoadedData: 'loadeddata',
|
||||
topLoad: 'load',
|
||||
topLoadedMetadata: 'loadedmetadata',
|
||||
topLoadStart: 'loadstart',
|
||||
topMouseDown: 'mousedown',
|
||||
topMouseMove: 'mousemove',
|
||||
topMouseOut: 'mouseout',
|
||||
topMouseOver: 'mouseover',
|
||||
topMouseUp: 'mouseup',
|
||||
topPaste: 'paste',
|
||||
topPause: 'pause',
|
||||
topPlay: 'play',
|
||||
topPlaying: 'playing',
|
||||
topProgress: 'progress',
|
||||
topRateChange: 'ratechange',
|
||||
topScroll: 'scroll',
|
||||
topSeeked: 'seeked',
|
||||
topSeeking: 'seeking',
|
||||
topSelectionChange: 'selectionchange',
|
||||
topStalled: 'stalled',
|
||||
topSuspend: 'suspend',
|
||||
topTextInput: 'textInput',
|
||||
topTimeUpdate: 'timeupdate',
|
||||
topToggle: 'toggle',
|
||||
topTouchCancel: 'touchcancel',
|
||||
topTouchEnd: 'touchend',
|
||||
topTouchMove: 'touchmove',
|
||||
topTouchStart: 'touchstart',
|
||||
topTransitionEnd: getVendorPrefixedEventName('transitionend') ||
|
||||
'transitionend',
|
||||
topVolumeChange: 'volumechange',
|
||||
topWaiting: 'waiting',
|
||||
topWheel: 'wheel',
|
||||
};
|
||||
|
||||
export type TopLevelTypes = $Enum<typeof topLevelTypes>;
|
||||
|
||||
var BrowserEventConstants = {
|
||||
topLevelTypes,
|
||||
};
|
||||
|
||||
module.exports = BrowserEventConstants;
|
|
@ -1,99 +0,0 @@
|
|||
/**
|
||||
* Copyright 2013-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 EventConstants
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
export type PropagationPhases = 'bubbled' | 'captured';
|
||||
|
||||
/**
|
||||
* Types of raw signals from the browser caught at the top level.
|
||||
*/
|
||||
var topLevelTypes = {
|
||||
topAbort: null,
|
||||
topAnimationEnd: null,
|
||||
topAnimationIteration: null,
|
||||
topAnimationStart: null,
|
||||
topBlur: null,
|
||||
topCancel: null,
|
||||
topCanPlay: null,
|
||||
topCanPlayThrough: null,
|
||||
topChange: null,
|
||||
topClick: null,
|
||||
topClose: null,
|
||||
topCompositionEnd: null,
|
||||
topCompositionStart: null,
|
||||
topCompositionUpdate: null,
|
||||
topContextMenu: null,
|
||||
topCopy: null,
|
||||
topCut: null,
|
||||
topDoubleClick: null,
|
||||
topDrag: null,
|
||||
topDragEnd: null,
|
||||
topDragEnter: null,
|
||||
topDragExit: null,
|
||||
topDragLeave: null,
|
||||
topDragOver: null,
|
||||
topDragStart: null,
|
||||
topDrop: null,
|
||||
topDurationChange: null,
|
||||
topEmptied: null,
|
||||
topEncrypted: null,
|
||||
topEnded: null,
|
||||
topError: null,
|
||||
topFocus: null,
|
||||
topInput: null,
|
||||
topInvalid: null,
|
||||
topKeyDown: null,
|
||||
topKeyPress: null,
|
||||
topKeyUp: null,
|
||||
topLoad: null,
|
||||
topLoadedData: null,
|
||||
topLoadedMetadata: null,
|
||||
topLoadStart: null,
|
||||
topMouseDown: null,
|
||||
topMouseMove: null,
|
||||
topMouseOut: null,
|
||||
topMouseOver: null,
|
||||
topMouseUp: null,
|
||||
topPaste: null,
|
||||
topPause: null,
|
||||
topPlay: null,
|
||||
topPlaying: null,
|
||||
topProgress: null,
|
||||
topRateChange: null,
|
||||
topReset: null,
|
||||
topScroll: null,
|
||||
topSeeked: null,
|
||||
topSeeking: null,
|
||||
topSelectionChange: null,
|
||||
topStalled: null,
|
||||
topSubmit: null,
|
||||
topSuspend: null,
|
||||
topTextInput: null,
|
||||
topTimeUpdate: null,
|
||||
topToggle: null,
|
||||
topTouchCancel: null,
|
||||
topTouchEnd: null,
|
||||
topTouchMove: null,
|
||||
topTouchStart: null,
|
||||
topTransitionEnd: null,
|
||||
topVolumeChange: null,
|
||||
topWaiting: null,
|
||||
topWheel: null,
|
||||
};
|
||||
|
||||
export type TopLevelTypes = $Enum<typeof topLevelTypes>;
|
||||
|
||||
var EventConstants = {
|
||||
topLevelTypes,
|
||||
};
|
||||
|
||||
module.exports = EventConstants;
|
|
@ -49,10 +49,12 @@ var executeDispatchesAndReleaseTopLevel = function(e) {
|
|||
};
|
||||
|
||||
function isInteractive(tag) {
|
||||
return tag === 'button' ||
|
||||
return (
|
||||
tag === 'button' ||
|
||||
tag === 'input' ||
|
||||
tag === 'select' ||
|
||||
tag === 'textarea';
|
||||
tag === 'textarea'
|
||||
);
|
||||
}
|
||||
|
||||
function shouldPreventMouseEvent(name, type, props) {
|
||||
|
@ -140,7 +142,8 @@ var EventPluginHub = {
|
|||
} else {
|
||||
const currentElement = inst._currentElement;
|
||||
if (
|
||||
typeof currentElement === 'string' || typeof currentElement === 'number'
|
||||
typeof currentElement === 'string' ||
|
||||
typeof currentElement === 'number'
|
||||
) {
|
||||
// Text node, let it bubble through.
|
||||
return null;
|
||||
|
|
|
@ -141,9 +141,8 @@ function publishRegistrationName(
|
|||
registrationName,
|
||||
);
|
||||
EventPluginRegistry.registrationNameModules[registrationName] = pluginModule;
|
||||
EventPluginRegistry.registrationNameDependencies[
|
||||
registrationName
|
||||
] = pluginModule.eventTypes[eventName].dependencies;
|
||||
EventPluginRegistry.registrationNameDependencies[registrationName] =
|
||||
pluginModule.eventTypes[eventName].dependencies;
|
||||
|
||||
if (__DEV__) {
|
||||
var lowerCasedName = registrationName.toLowerCase();
|
||||
|
|
|
@ -41,9 +41,11 @@ var injection = {
|
|||
};
|
||||
|
||||
function isEndish(topLevelType) {
|
||||
return topLevelType === 'topMouseUp' ||
|
||||
return (
|
||||
topLevelType === 'topMouseUp' ||
|
||||
topLevelType === 'topTouchEnd' ||
|
||||
topLevelType === 'topTouchCancel';
|
||||
topLevelType === 'topTouchCancel'
|
||||
);
|
||||
}
|
||||
|
||||
function isMoveish(topLevelType) {
|
||||
|
|
|
@ -18,7 +18,7 @@ var accumulateInto = require('accumulateInto');
|
|||
var forEachAccumulated = require('forEachAccumulated');
|
||||
var warning = require('fbjs/lib/warning');
|
||||
|
||||
import type {PropagationPhases} from 'EventConstants';
|
||||
type PropagationPhases = 'bubbled' | 'captured';
|
||||
|
||||
var getListener = EventPluginHub.getListener;
|
||||
|
||||
|
@ -27,9 +27,8 @@ var getListener = EventPluginHub.getListener;
|
|||
* "phases" of propagation. This finds listeners by a given phase.
|
||||
*/
|
||||
function listenerAtPhase(inst, event, propagationPhase: PropagationPhases) {
|
||||
var registrationName = event.dispatchConfig.phasedRegistrationNames[
|
||||
propagationPhase
|
||||
];
|
||||
var registrationName =
|
||||
event.dispatchConfig.phasedRegistrationNames[propagationPhase];
|
||||
return getListener(inst, registrationName);
|
||||
}
|
||||
|
||||
|
|
|
@ -25,14 +25,12 @@ export type DispatchConfig = {
|
|||
registrationName?: string,
|
||||
};
|
||||
|
||||
export type ReactSyntheticEvent =
|
||||
& {
|
||||
export type ReactSyntheticEvent = {
|
||||
dispatchConfig: DispatchConfig,
|
||||
getPooled: (
|
||||
dispatchConfig: DispatchConfig,
|
||||
getPooled: (
|
||||
dispatchConfig: DispatchConfig,
|
||||
targetInst: ReactInstance,
|
||||
nativeTarget: Event,
|
||||
nativeEventTarget: EventTarget,
|
||||
) => ReactSyntheticEvent,
|
||||
}
|
||||
& SyntheticEvent;
|
||||
targetInst: ReactInstance,
|
||||
nativeTarget: Event,
|
||||
nativeEventTarget: EventTarget,
|
||||
) => ReactSyntheticEvent,
|
||||
} & SyntheticEvent;
|
||||
|
|
|
@ -24,7 +24,8 @@ var isMoveish = EventPluginUtils.isMoveish;
|
|||
var isEndish = EventPluginUtils.isEndish;
|
||||
var executeDirectDispatch = EventPluginUtils.executeDirectDispatch;
|
||||
var hasDispatches = EventPluginUtils.hasDispatches;
|
||||
var executeDispatchesInOrderStopAtTrue = EventPluginUtils.executeDispatchesInOrderStopAtTrue;
|
||||
var executeDispatchesInOrderStopAtTrue =
|
||||
EventPluginUtils.executeDispatchesInOrderStopAtTrue;
|
||||
|
||||
/**
|
||||
* Instance of element that should respond to touch/move types of interactions,
|
||||
|
@ -375,9 +376,11 @@ function setResponderAndExtractTransfer(
|
|||
nativeEvent,
|
||||
nativeEventTarget,
|
||||
);
|
||||
terminationRequestEvent.touchHistory = ResponderTouchHistoryStore.touchHistory;
|
||||
terminationRequestEvent.touchHistory =
|
||||
ResponderTouchHistoryStore.touchHistory;
|
||||
EventPropagators.accumulateDirectDispatches(terminationRequestEvent);
|
||||
var shouldSwitch = !hasDispatches(terminationRequestEvent) ||
|
||||
var shouldSwitch =
|
||||
!hasDispatches(terminationRequestEvent) ||
|
||||
executeDirectDispatch(terminationRequestEvent);
|
||||
if (!terminationRequestEvent.isPersistent()) {
|
||||
terminationRequestEvent.constructor.release(terminationRequestEvent);
|
||||
|
@ -417,18 +420,20 @@ function setResponderAndExtractTransfer(
|
|||
* element to claim responder status. Any start event could trigger a transfer
|
||||
* of responderInst. Any move event could trigger a transfer.
|
||||
*
|
||||
* @param {string} topLevelType Record from `EventConstants`.
|
||||
* @param {string} topLevelType Record from `BrowserEventConstants`.
|
||||
* @return {boolean} True if a transfer of responder could possibly occur.
|
||||
*/
|
||||
function canTriggerTransfer(topLevelType, topLevelInst, nativeEvent) {
|
||||
return topLevelInst &&
|
||||
return (
|
||||
topLevelInst &&
|
||||
// responderIgnoreScroll: We are trying to migrate away from specifically
|
||||
// tracking native scroll events here and responderIgnoreScroll indicates we
|
||||
// will send topTouchCancel to handle canceling touch events instead
|
||||
((topLevelType === 'topScroll' && !nativeEvent.responderIgnoreScroll) ||
|
||||
(trackedTouchCount > 0 && topLevelType === 'topSelectionChange') ||
|
||||
isStartish(topLevelType) ||
|
||||
isMoveish(topLevelType));
|
||||
isMoveish(topLevelType))
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -530,9 +535,10 @@ var ResponderEventPlugin = {
|
|||
extracted = accumulate(extracted, gesture);
|
||||
}
|
||||
|
||||
var isResponderTerminate = responderInst &&
|
||||
topLevelType === 'topTouchCancel';
|
||||
var isResponderRelease = responderInst &&
|
||||
var isResponderTerminate =
|
||||
responderInst && topLevelType === 'topTouchCancel';
|
||||
var isResponderRelease =
|
||||
responderInst &&
|
||||
!isResponderTerminate &&
|
||||
isEndish(topLevelType) &&
|
||||
noResponderTouches(nativeEvent);
|
||||
|
@ -552,7 +558,8 @@ var ResponderEventPlugin = {
|
|||
changeResponder(null);
|
||||
}
|
||||
|
||||
var numberActiveTouches = ResponderTouchHistoryStore.touchHistory.numberActiveTouches;
|
||||
var numberActiveTouches =
|
||||
ResponderTouchHistoryStore.touchHistory.numberActiveTouches;
|
||||
if (
|
||||
ResponderEventPlugin.GlobalInteractionHandler &&
|
||||
numberActiveTouches !== previousActiveTouches
|
||||
|
|
|
@ -17,11 +17,7 @@ const EventPluginUtils = require('EventPluginUtils');
|
|||
const invariant = require('fbjs/lib/invariant');
|
||||
const warning = require('fbjs/lib/warning');
|
||||
|
||||
const {
|
||||
isEndish,
|
||||
isMoveish,
|
||||
isStartish,
|
||||
} = EventPluginUtils;
|
||||
const {isEndish, isMoveish, isStartish} = EventPluginUtils;
|
||||
|
||||
/**
|
||||
* Tracks the position and time of each active touch by `touch.identifier`. We
|
||||
|
@ -193,9 +189,8 @@ const ResponderTouchHistoryStore = {
|
|||
nativeEvent.changedTouches.forEach(recordTouchStart);
|
||||
touchHistory.numberActiveTouches = nativeEvent.touches.length;
|
||||
if (touchHistory.numberActiveTouches === 1) {
|
||||
touchHistory.indexOfSingleActiveTouch = nativeEvent.touches[
|
||||
0
|
||||
].identifier;
|
||||
touchHistory.indexOfSingleActiveTouch =
|
||||
nativeEvent.touches[0].identifier;
|
||||
}
|
||||
} else if (isEndish(topLevelType)) {
|
||||
nativeEvent.changedTouches.forEach(recordTouchEnd);
|
||||
|
|
|
@ -256,15 +256,13 @@ var registerTestHandlers = function(eventTestConfig, readableIDToID) {
|
|||
var hasTwoPhase = !!oneEventTypeTestConfig.bubbled;
|
||||
if (hasTwoPhase) {
|
||||
registerOneEventType(
|
||||
ResponderEventPlugin.eventTypes[
|
||||
eventName
|
||||
].phasedRegistrationNames.bubbled,
|
||||
ResponderEventPlugin.eventTypes[eventName].phasedRegistrationNames
|
||||
.bubbled,
|
||||
oneEventTypeTestConfig.bubbled,
|
||||
);
|
||||
registerOneEventType(
|
||||
ResponderEventPlugin.eventTypes[
|
||||
eventName
|
||||
].phasedRegistrationNames.captured,
|
||||
ResponderEventPlugin.eventTypes[eventName].phasedRegistrationNames
|
||||
.captured,
|
||||
oneEventTypeTestConfig.captured,
|
||||
);
|
||||
} else {
|
||||
|
|
|
@ -0,0 +1,101 @@
|
|||
/**
|
||||
* Copyright 2013-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 getVendorPrefixedEventName
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
var ExecutionEnvironment = require('fbjs/lib/ExecutionEnvironment');
|
||||
|
||||
/**
|
||||
* Generate a mapping of standard vendor prefixes using the defined style property and event name.
|
||||
*
|
||||
* @param {string} styleProp
|
||||
* @param {string} eventName
|
||||
* @returns {object}
|
||||
*/
|
||||
function makePrefixMap(styleProp, eventName) {
|
||||
var prefixes = {};
|
||||
|
||||
prefixes[styleProp.toLowerCase()] = eventName.toLowerCase();
|
||||
prefixes['Webkit' + styleProp] = 'webkit' + eventName;
|
||||
prefixes['Moz' + styleProp] = 'moz' + eventName;
|
||||
prefixes['ms' + styleProp] = 'MS' + eventName;
|
||||
prefixes['O' + styleProp] = 'o' + eventName.toLowerCase();
|
||||
|
||||
return prefixes;
|
||||
}
|
||||
|
||||
/**
|
||||
* A list of event names to a configurable list of vendor prefixes.
|
||||
*/
|
||||
var vendorPrefixes = {
|
||||
animationend: makePrefixMap('Animation', 'AnimationEnd'),
|
||||
animationiteration: makePrefixMap('Animation', 'AnimationIteration'),
|
||||
animationstart: makePrefixMap('Animation', 'AnimationStart'),
|
||||
transitionend: makePrefixMap('Transition', 'TransitionEnd'),
|
||||
};
|
||||
|
||||
/**
|
||||
* Event names that have already been detected and prefixed (if applicable).
|
||||
*/
|
||||
var prefixedEventNames = {};
|
||||
|
||||
/**
|
||||
* Element to check for prefixes on.
|
||||
*/
|
||||
var style = {};
|
||||
|
||||
/**
|
||||
* Bootstrap if a DOM exists.
|
||||
*/
|
||||
if (ExecutionEnvironment.canUseDOM) {
|
||||
style = document.createElement('div').style;
|
||||
|
||||
// On some platforms, in particular some releases of Android 4.x,
|
||||
// the un-prefixed "animation" and "transition" properties are defined on the
|
||||
// style object but the events that fire will still be prefixed, so we need
|
||||
// to check if the un-prefixed events are usable, and if not remove them from the map.
|
||||
if (!('AnimationEvent' in window)) {
|
||||
delete vendorPrefixes.animationend.animation;
|
||||
delete vendorPrefixes.animationiteration.animation;
|
||||
delete vendorPrefixes.animationstart.animation;
|
||||
}
|
||||
|
||||
// Same as above
|
||||
if (!('TransitionEvent' in window)) {
|
||||
delete vendorPrefixes.transitionend.transition;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempts to determine the correct vendor prefixed event name.
|
||||
*
|
||||
* @param {string} eventName
|
||||
* @returns {string}
|
||||
*/
|
||||
function getVendorPrefixedEventName(eventName) {
|
||||
if (prefixedEventNames[eventName]) {
|
||||
return prefixedEventNames[eventName];
|
||||
} else if (!vendorPrefixes[eventName]) {
|
||||
return eventName;
|
||||
}
|
||||
|
||||
var prefixMap = vendorPrefixes[eventName];
|
||||
|
||||
for (var styleProp in prefixMap) {
|
||||
if (prefixMap.hasOwnProperty(styleProp) && styleProp in style) {
|
||||
return (prefixedEventNames[eventName] = prefixMap[styleProp]);
|
||||
}
|
||||
}
|
||||
|
||||
return '';
|
||||
}
|
||||
|
||||
module.exports = getVendorPrefixedEventName;
|
|
@ -34,9 +34,11 @@ function shouldUpdateReactComponent(prevElement, nextElement) {
|
|||
if (prevType === 'string' || prevType === 'number') {
|
||||
return nextType === 'string' || nextType === 'number';
|
||||
} else {
|
||||
return nextType === 'object' &&
|
||||
return (
|
||||
nextType === 'object' &&
|
||||
prevElement.type === nextElement.type &&
|
||||
prevElement.key === nextElement.key;
|
||||
prevElement.key === nextElement.key
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -17,7 +17,7 @@ var ReactReconciler = require('ReactReconciler');
|
|||
|
||||
var instantiateReactComponent = require('instantiateReactComponent');
|
||||
var shouldUpdateReactComponent = require('shouldUpdateReactComponent');
|
||||
var traverseAllChildren = require('traverseAllChildren');
|
||||
var traverseStackChildren = require('traverseStackChildren');
|
||||
var warning = require('fbjs/lib/warning');
|
||||
|
||||
var ReactComponentTreeHook;
|
||||
|
@ -32,7 +32,8 @@ if (
|
|||
// https://github.com/facebook/react/issues/7240
|
||||
// Remove the inline requires when we don't need them anymore:
|
||||
// https://github.com/facebook/react/pull/7178
|
||||
ReactComponentTreeHook = require('react/lib/ReactComponentTreeHook');
|
||||
ReactComponentTreeHook = require('ReactGlobalSharedState')
|
||||
.ReactComponentTreeHook;
|
||||
}
|
||||
|
||||
function instantiateChild(childInstances, child, name, selfDebugID) {
|
||||
|
@ -40,7 +41,8 @@ function instantiateChild(childInstances, child, name, selfDebugID) {
|
|||
var keyUnique = childInstances[name] === undefined;
|
||||
if (__DEV__) {
|
||||
if (!ReactComponentTreeHook) {
|
||||
ReactComponentTreeHook = require('react/lib/ReactComponentTreeHook');
|
||||
ReactComponentTreeHook = require('ReactGlobalSharedState')
|
||||
.ReactComponentTreeHook;
|
||||
}
|
||||
if (!keyUnique) {
|
||||
warning(
|
||||
|
@ -84,14 +86,14 @@ var ReactChildReconciler = {
|
|||
var childInstances = {};
|
||||
|
||||
if (__DEV__) {
|
||||
traverseAllChildren(
|
||||
traverseStackChildren(
|
||||
nestedChildNodes,
|
||||
(childInsts, child, name) =>
|
||||
instantiateChild(childInsts, child, name, selfDebugID),
|
||||
childInstances,
|
||||
);
|
||||
} else {
|
||||
traverseAllChildren(nestedChildNodes, instantiateChild, childInstances);
|
||||
traverseStackChildren(nestedChildNodes, instantiateChild, childInstances);
|
||||
}
|
||||
return childInstances;
|
||||
},
|
||||
|
@ -147,7 +149,8 @@ var ReactChildReconciler = {
|
|||
nextChildren[name] = prevChild;
|
||||
} else {
|
||||
if (
|
||||
!ReactFeatureFlags.prepareNewChildrenBeforeUnmountInStack && prevChild
|
||||
!ReactFeatureFlags.prepareNewChildrenBeforeUnmountInStack &&
|
||||
prevChild
|
||||
) {
|
||||
removedNodes[name] = ReactReconciler.getHostNode(prevChild);
|
||||
ReactReconciler.unmountComponent(
|
||||
|
@ -171,7 +174,8 @@ var ReactChildReconciler = {
|
|||
);
|
||||
mountImages.push(nextChildMountImage);
|
||||
if (
|
||||
ReactFeatureFlags.prepareNewChildrenBeforeUnmountInStack && prevChild
|
||||
ReactFeatureFlags.prepareNewChildrenBeforeUnmountInStack &&
|
||||
prevChild
|
||||
) {
|
||||
removedNodes[name] = ReactReconciler.getHostNode(prevChild);
|
||||
ReactReconciler.unmountComponent(
|
||||
|
|
|
@ -43,8 +43,10 @@ var ReactComponentEnvironment = {
|
|||
!injected,
|
||||
'ReactCompositeComponent: injectEnvironment() can only be called once.',
|
||||
);
|
||||
ReactComponentEnvironment.replaceNodeWithMarkup = environment.replaceNodeWithMarkup;
|
||||
ReactComponentEnvironment.processChildrenUpdates = environment.processChildrenUpdates;
|
||||
ReactComponentEnvironment.replaceNodeWithMarkup =
|
||||
environment.replaceNodeWithMarkup;
|
||||
ReactComponentEnvironment.processChildrenUpdates =
|
||||
environment.processChildrenUpdates;
|
||||
injected = true;
|
||||
},
|
||||
},
|
||||
|
|
|
@ -14,20 +14,20 @@
|
|||
var React = require('react');
|
||||
var ReactComponentEnvironment = require('ReactComponentEnvironment');
|
||||
var ReactCompositeComponentTypes = require('ReactCompositeComponentTypes');
|
||||
var ReactCurrentOwner = require('react/lib/ReactCurrentOwner');
|
||||
var ReactErrorUtils = require('ReactErrorUtils');
|
||||
var ReactFeatureFlags = require('ReactFeatureFlags');
|
||||
var ReactInstanceMap = require('ReactInstanceMap');
|
||||
var ReactInstrumentation = require('ReactInstrumentation');
|
||||
var ReactNodeTypes = require('ReactNodeTypes');
|
||||
var ReactReconciler = require('ReactReconciler');
|
||||
var {ReactCurrentOwner} = require('ReactGlobalSharedState');
|
||||
|
||||
if (__DEV__) {
|
||||
var checkReactTypeSpec = require('checkReactTypeSpec');
|
||||
var ReactDebugCurrentFrame = require('react/lib/ReactDebugCurrentFrame');
|
||||
var {ReactDebugCurrentFrame} = require('ReactGlobalSharedState');
|
||||
var warningAboutMissingGetChildContext = {};
|
||||
}
|
||||
|
||||
var checkPropTypes = require('prop-types/checkPropTypes');
|
||||
var emptyObject = require('fbjs/lib/emptyObject');
|
||||
var invariant = require('fbjs/lib/invariant');
|
||||
var shallowEqual = require('fbjs/lib/shallowEqual');
|
||||
|
@ -222,9 +222,8 @@ var ReactCompositeComponent = {
|
|||
}
|
||||
|
||||
var propsMutated = inst.props !== publicProps;
|
||||
var componentName = Component.displayName ||
|
||||
Component.name ||
|
||||
'Component';
|
||||
var componentName =
|
||||
Component.displayName || Component.name || 'Component';
|
||||
|
||||
warning(
|
||||
inst.props === undefined || !propsMutated,
|
||||
|
@ -300,11 +299,30 @@ var ReactCompositeComponent = {
|
|||
'componentWillRecieveProps(). Did you mean componentWillReceiveProps()?',
|
||||
this.getName() || 'A component',
|
||||
);
|
||||
if (
|
||||
isPureComponent(Component) &&
|
||||
typeof inst.shouldComponentUpdate !== 'undefined'
|
||||
) {
|
||||
warning(
|
||||
false,
|
||||
'%s has a method called shouldComponentUpdate(). ' +
|
||||
'shouldComponentUpdate should not be used when extending React.PureComponent. ' +
|
||||
'Please extend React.Component if shouldComponentUpdate is used.',
|
||||
this.getName() || 'A pure component',
|
||||
);
|
||||
}
|
||||
warning(
|
||||
!inst.defaultProps,
|
||||
'Setting defaultProps as an instance property on %s is not supported and will be ignored.' +
|
||||
' Instead, define defaultProps as a static property on %s.',
|
||||
this.getName() || 'a component',
|
||||
this.getName() || 'a component',
|
||||
);
|
||||
}
|
||||
|
||||
var initialState = inst.state;
|
||||
if (initialState === undefined) {
|
||||
inst.state = (initialState = null);
|
||||
inst.state = initialState = null;
|
||||
}
|
||||
invariant(
|
||||
typeof initialState === 'object' && !Array.isArray(initialState),
|
||||
|
@ -730,7 +748,13 @@ var ReactCompositeComponent = {
|
|||
_checkContextTypes: function(typeSpecs, values, location: string) {
|
||||
if (__DEV__) {
|
||||
ReactDebugCurrentFrame.current = this._debugID;
|
||||
checkReactTypeSpec(typeSpecs, values, location, this.getName());
|
||||
checkPropTypes(
|
||||
typeSpecs,
|
||||
values,
|
||||
location,
|
||||
this.getName(),
|
||||
ReactDebugCurrentFrame.getStackAddendum,
|
||||
);
|
||||
ReactDebugCurrentFrame.current = null;
|
||||
}
|
||||
},
|
||||
|
@ -892,7 +916,8 @@ var ReactCompositeComponent = {
|
|||
}
|
||||
} else {
|
||||
if (this._compositeType === ReactCompositeComponentTypes.PureClass) {
|
||||
shouldUpdate = !shallowEqual(prevProps, nextProps) ||
|
||||
shouldUpdate =
|
||||
!shallowEqual(prevProps, nextProps) ||
|
||||
!shallowEqual(inst.state, nextState);
|
||||
}
|
||||
}
|
||||
|
@ -998,11 +1023,9 @@ var ReactCompositeComponent = {
|
|||
var hasComponentDidUpdate = !!inst.componentDidUpdate;
|
||||
var prevProps;
|
||||
var prevState;
|
||||
var prevContext;
|
||||
if (hasComponentDidUpdate) {
|
||||
prevProps = inst.props;
|
||||
prevState = inst.state;
|
||||
prevContext = inst.context;
|
||||
}
|
||||
|
||||
if (inst.componentWillUpdate) {
|
||||
|
@ -1036,12 +1059,7 @@ var ReactCompositeComponent = {
|
|||
if (__DEV__) {
|
||||
transaction.getReactMountReady().enqueue(() => {
|
||||
measureLifeCyclePerf(
|
||||
inst.componentDidUpdate.bind(
|
||||
inst,
|
||||
prevProps,
|
||||
prevState,
|
||||
prevContext,
|
||||
),
|
||||
inst.componentDidUpdate.bind(inst, prevProps, prevState),
|
||||
this._debugID,
|
||||
'componentDidUpdate',
|
||||
);
|
||||
|
@ -1050,12 +1068,7 @@ var ReactCompositeComponent = {
|
|||
transaction
|
||||
.getReactMountReady()
|
||||
.enqueue(
|
||||
inst.componentDidUpdate.bind(
|
||||
inst,
|
||||
prevProps,
|
||||
prevState,
|
||||
prevContext,
|
||||
),
|
||||
inst.componentDidUpdate.bind(inst, prevProps, prevState),
|
||||
inst,
|
||||
);
|
||||
}
|
||||
|
@ -1303,11 +1316,13 @@ var ReactCompositeComponent = {
|
|||
getName: function() {
|
||||
var type = this._currentElement.type;
|
||||
var constructor = this._instance && this._instance.constructor;
|
||||
return type.displayName ||
|
||||
return (
|
||||
type.displayName ||
|
||||
(constructor && constructor.displayName) ||
|
||||
type.name ||
|
||||
(constructor && constructor.name) ||
|
||||
null;
|
||||
null
|
||||
);
|
||||
},
|
||||
|
||||
/**
|
||||
|
|
|
@ -15,12 +15,12 @@ var ReactComponentEnvironment = require('ReactComponentEnvironment');
|
|||
var ReactInstanceMap = require('ReactInstanceMap');
|
||||
var ReactInstrumentation = require('ReactInstrumentation');
|
||||
|
||||
var ReactCurrentOwner = require('react/lib/ReactCurrentOwner');
|
||||
var ReactReconciler = require('ReactReconciler');
|
||||
var ReactChildReconciler = require('ReactChildReconciler');
|
||||
var {ReactCurrentOwner} = require('ReactGlobalSharedState');
|
||||
|
||||
var emptyFunction = require('fbjs/lib/emptyFunction');
|
||||
var flattenChildren = require('flattenChildren');
|
||||
var flattenStackChildren = require('flattenStackChildren');
|
||||
var invariant = require('fbjs/lib/invariant');
|
||||
|
||||
/**
|
||||
|
@ -212,7 +212,7 @@ var ReactMultiChild = {
|
|||
if (this._currentElement) {
|
||||
try {
|
||||
ReactCurrentOwner.current = this._currentElement._owner;
|
||||
nextChildren = flattenChildren(
|
||||
nextChildren = flattenStackChildren(
|
||||
nextNestedChildrenElements,
|
||||
selfDebugID,
|
||||
);
|
||||
|
@ -233,7 +233,10 @@ var ReactMultiChild = {
|
|||
return nextChildren;
|
||||
}
|
||||
}
|
||||
nextChildren = flattenChildren(nextNestedChildrenElements, selfDebugID);
|
||||
nextChildren = flattenStackChildren(
|
||||
nextNestedChildrenElements,
|
||||
selfDebugID,
|
||||
);
|
||||
ReactChildReconciler.updateChildren(
|
||||
prevChildren,
|
||||
nextChildren,
|
||||
|
|
|
@ -21,7 +21,7 @@ var ReactRef = {};
|
|||
|
||||
if (__DEV__) {
|
||||
var ReactCompositeComponentTypes = require('ReactCompositeComponentTypes');
|
||||
var ReactComponentTreeHook = require('react/lib/ReactComponentTreeHook');
|
||||
var {ReactComponentTreeHook} = require('ReactGlobalSharedState');
|
||||
var warning = require('fbjs/lib/warning');
|
||||
|
||||
var warnedAboutStatelessRefs = {};
|
||||
|
@ -47,9 +47,8 @@ function attachRef(ref, component, owner) {
|
|||
let warningKey = ownerName || component._debugID;
|
||||
let element = component._currentElement;
|
||||
if (element && element._source) {
|
||||
warningKey = element._source.fileName +
|
||||
':' +
|
||||
element._source.lineNumber;
|
||||
warningKey =
|
||||
element._source.fileName + ':' + element._source.lineNumber;
|
||||
}
|
||||
if (!warnedAboutStatelessRefs[warningKey]) {
|
||||
warnedAboutStatelessRefs[warningKey] = true;
|
||||
|
@ -124,9 +123,11 @@ ReactRef.shouldUpdateRefs = function(
|
|||
nextOwner = nextElement._owner;
|
||||
}
|
||||
|
||||
return prevRef !== nextRef ||
|
||||
return (
|
||||
prevRef !== nextRef ||
|
||||
// If owner changes but we have an unchanged function ref, don't update refs
|
||||
(typeof nextRef === 'string' && nextOwner !== prevOwner);
|
||||
(typeof nextRef === 'string' && nextOwner !== prevOwner)
|
||||
);
|
||||
};
|
||||
|
||||
ReactRef.detachRefs = function(
|
||||
|
|
|
@ -11,10 +11,10 @@
|
|||
|
||||
'use strict';
|
||||
|
||||
var ReactCurrentOwner = require('react/lib/ReactCurrentOwner');
|
||||
var ReactInstanceMap = require('ReactInstanceMap');
|
||||
var ReactInstrumentation = require('ReactInstrumentation');
|
||||
var ReactUpdates = require('ReactUpdates');
|
||||
var {ReactCurrentOwner} = require('ReactGlobalSharedState');
|
||||
|
||||
if (__DEV__) {
|
||||
var warning = require('fbjs/lib/warning');
|
||||
|
@ -226,7 +226,8 @@ var ReactUpdateQueue = {
|
|||
return;
|
||||
}
|
||||
|
||||
var queue = internalInstance._pendingStateQueue ||
|
||||
var queue =
|
||||
internalInstance._pendingStateQueue ||
|
||||
(internalInstance._pendingStateQueue = []);
|
||||
queue.push(partialState);
|
||||
|
||||
|
|
|
@ -124,14 +124,16 @@ var TransactionImpl = {
|
|||
*
|
||||
* @return {*} Return value from `method`.
|
||||
*/
|
||||
perform: function<A, B, C, D, E, F, G, T: (
|
||||
a: A,
|
||||
b: B,
|
||||
c: C,
|
||||
d: D,
|
||||
e: E,
|
||||
f: F,
|
||||
) => G>(method: T, scope: any, a: A, b: B, c: C, d: D, e: E, f: F): G {
|
||||
perform: function<
|
||||
A,
|
||||
B,
|
||||
C,
|
||||
D,
|
||||
E,
|
||||
F,
|
||||
G,
|
||||
T: (a: A, b: B, c: C, d: D, e: E, f: F) => G
|
||||
>(method: T, scope: any, a: A, b: B, c: C, d: D, e: E, f: F): G {
|
||||
invariant(
|
||||
!this.isInTransaction(),
|
||||
'Transaction.perform(...): Cannot initialize a transaction when there ' +
|
||||
|
|
|
@ -6,14 +6,14 @@
|
|||
* 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 flattenChildren
|
||||
* @providesModule flattenStackChildren
|
||||
* @flow
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
var KeyEscapeUtils = require('KeyEscapeUtils');
|
||||
var traverseAllChildren = require('traverseAllChildren');
|
||||
var traverseStackChildren = require('traverseStackChildren');
|
||||
var warning = require('fbjs/lib/warning');
|
||||
|
||||
var ReactComponentTreeHook;
|
||||
|
@ -28,7 +28,8 @@ if (
|
|||
// https://github.com/facebook/react/issues/7240
|
||||
// Remove the inline requires when we don't need them anymore:
|
||||
// https://github.com/facebook/react/pull/7178
|
||||
ReactComponentTreeHook = require('react/lib/ReactComponentTreeHook');
|
||||
ReactComponentTreeHook = require('ReactGlobalSharedState')
|
||||
.ReactComponentTreeHook;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -49,7 +50,8 @@ function flattenSingleChildIntoContext(
|
|||
const keyUnique = result[name] === undefined;
|
||||
if (__DEV__) {
|
||||
if (!ReactComponentTreeHook) {
|
||||
ReactComponentTreeHook = require('react/lib/ReactComponentTreeHook');
|
||||
ReactComponentTreeHook = require('ReactGlobalSharedState')
|
||||
.ReactComponentTreeHook;
|
||||
}
|
||||
if (!keyUnique) {
|
||||
warning(
|
||||
|
@ -73,7 +75,7 @@ function flattenSingleChildIntoContext(
|
|||
* children will not be included in the resulting object.
|
||||
* @return {!object} flattened children keyed by name.
|
||||
*/
|
||||
function flattenChildren(
|
||||
function flattenStackChildren(
|
||||
children: ReactElement<any>,
|
||||
selfDebugID?: number,
|
||||
): ?{[name: string]: ReactElement<any>} {
|
||||
|
@ -83,7 +85,7 @@ function flattenChildren(
|
|||
var result = {};
|
||||
|
||||
if (__DEV__) {
|
||||
traverseAllChildren(
|
||||
traverseStackChildren(
|
||||
children,
|
||||
(traverseContext, child, name) =>
|
||||
flattenSingleChildIntoContext(
|
||||
|
@ -95,9 +97,9 @@ function flattenChildren(
|
|||
result,
|
||||
);
|
||||
} else {
|
||||
traverseAllChildren(children, flattenSingleChildIntoContext, result);
|
||||
traverseStackChildren(children, flattenSingleChildIntoContext, result);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
module.exports = flattenChildren;
|
||||
module.exports = flattenStackChildren;
|
|
@ -42,10 +42,12 @@ function getDeclarationErrorAddendum(owner) {
|
|||
* @return {boolean} Returns true if this is a valid internal type.
|
||||
*/
|
||||
function isInternalComponentType(type) {
|
||||
return typeof type === 'function' &&
|
||||
return (
|
||||
typeof type === 'function' &&
|
||||
typeof type.prototype !== 'undefined' &&
|
||||
typeof type.prototype.mountComponent === 'function' &&
|
||||
typeof type.prototype.receiveComponent === 'function';
|
||||
typeof type.prototype.receiveComponent === 'function'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -73,7 +75,8 @@ function instantiateReactComponent(node, shouldHaveDebugID) {
|
|||
type !== null &&
|
||||
Object.keys(type).length === 0)
|
||||
) {
|
||||
info += ' You likely forgot to export your component from the file ' +
|
||||
info +=
|
||||
' You likely forgot to export your component from the file ' +
|
||||
"it's defined in.";
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,12 +6,11 @@
|
|||
* 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 traverseAllChildren
|
||||
* @providesModule traverseStackChildren
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
var ReactCurrentOwner = require('react/lib/ReactCurrentOwner');
|
||||
var REACT_ELEMENT_TYPE = require('ReactElementSymbol');
|
||||
|
||||
var getIteratorFn = require('getIteratorFn');
|
||||
|
@ -19,6 +18,12 @@ var invariant = require('fbjs/lib/invariant');
|
|||
var KeyEscapeUtils = require('KeyEscapeUtils');
|
||||
var warning = require('fbjs/lib/warning');
|
||||
|
||||
if (__DEV__) {
|
||||
var {
|
||||
getCurrentStackAddendum,
|
||||
} = require('ReactGlobalSharedState').ReactComponentTreeHook;
|
||||
}
|
||||
|
||||
var SEPARATOR = '.';
|
||||
var SUBSEPARATOR = ':';
|
||||
|
||||
|
@ -61,7 +66,7 @@ function getComponentKey(component, index) {
|
|||
* process.
|
||||
* @return {!number} The number of children in this subtree.
|
||||
*/
|
||||
function traverseAllChildrenImpl(
|
||||
function traverseStackChildrenImpl(
|
||||
children,
|
||||
nameSoFar,
|
||||
callback,
|
||||
|
@ -101,7 +106,7 @@ function traverseAllChildrenImpl(
|
|||
for (var i = 0; i < children.length; i++) {
|
||||
child = children[i];
|
||||
nextName = nextNamePrefix + getComponentKey(child, i);
|
||||
subtreeCount += traverseAllChildrenImpl(
|
||||
subtreeCount += traverseStackChildrenImpl(
|
||||
child,
|
||||
nextName,
|
||||
callback,
|
||||
|
@ -114,21 +119,12 @@ function traverseAllChildrenImpl(
|
|||
if (__DEV__) {
|
||||
// Warn about using Maps as children
|
||||
if (iteratorFn === children.entries) {
|
||||
let mapsAsChildrenAddendum = '';
|
||||
if (ReactCurrentOwner.current) {
|
||||
var mapsAsChildrenOwnerName = ReactCurrentOwner.current.getName();
|
||||
if (mapsAsChildrenOwnerName) {
|
||||
mapsAsChildrenAddendum = '\n\nCheck the render method of `' +
|
||||
mapsAsChildrenOwnerName +
|
||||
'`.';
|
||||
}
|
||||
}
|
||||
warning(
|
||||
didWarnAboutMaps,
|
||||
'Using Maps as children is unsupported and will likely yield ' +
|
||||
'unexpected results. Convert it to a sequence/iterable of keyed ' +
|
||||
'ReactElements instead.%s',
|
||||
mapsAsChildrenAddendum,
|
||||
getCurrentStackAddendum(),
|
||||
);
|
||||
didWarnAboutMaps = true;
|
||||
}
|
||||
|
@ -140,7 +136,7 @@ function traverseAllChildrenImpl(
|
|||
while (!(step = iterator.next()).done) {
|
||||
child = step.value;
|
||||
nextName = nextNamePrefix + getComponentKey(child, ii++);
|
||||
subtreeCount += traverseAllChildrenImpl(
|
||||
subtreeCount += traverseStackChildrenImpl(
|
||||
child,
|
||||
nextName,
|
||||
callback,
|
||||
|
@ -150,14 +146,10 @@ function traverseAllChildrenImpl(
|
|||
} else if (type === 'object') {
|
||||
var addendum = '';
|
||||
if (__DEV__) {
|
||||
addendum = ' If you meant to render a collection of children, use an array ' +
|
||||
'instead.';
|
||||
if (ReactCurrentOwner.current) {
|
||||
var name = ReactCurrentOwner.current.getName();
|
||||
if (name) {
|
||||
addendum += '\n\nCheck the render method of `' + name + '`.';
|
||||
}
|
||||
}
|
||||
addendum =
|
||||
' If you meant to render a collection of children, use an array ' +
|
||||
'instead.' +
|
||||
getCurrentStackAddendum();
|
||||
}
|
||||
var childrenString = '' + children;
|
||||
invariant(
|
||||
|
@ -178,8 +170,8 @@ function traverseAllChildrenImpl(
|
|||
* Traverses children that are typically specified as `props.children`, but
|
||||
* might also be specified through attributes:
|
||||
*
|
||||
* - `traverseAllChildren(this.props.children, ...)`
|
||||
* - `traverseAllChildren(this.props.leftPanelChildren, ...)`
|
||||
* - `traverseStackChildren(this.props.children, ...)`
|
||||
* - `traverseStackChildren(this.props.leftPanelChildren, ...)`
|
||||
*
|
||||
* The `traverseContext` is an optional argument that is passed through the
|
||||
* entire traversal. It can be used to store accumulations or anything else that
|
||||
|
@ -190,12 +182,12 @@ function traverseAllChildrenImpl(
|
|||
* @param {?*} traverseContext Context for traversal.
|
||||
* @return {!number} The number of children in this subtree.
|
||||
*/
|
||||
function traverseAllChildren(children, callback, traverseContext) {
|
||||
function traverseStackChildren(children, callback, traverseContext) {
|
||||
if (children == null) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return traverseAllChildrenImpl(children, '', callback, traverseContext);
|
||||
return traverseStackChildrenImpl(children, '', callback, traverseContext);
|
||||
}
|
||||
|
||||
module.exports = traverseAllChildren;
|
||||
module.exports = traverseStackChildren;
|
|
@ -76,15 +76,6 @@ let rethrowCaughtError = function() {
|
|||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Call a function while guarding against errors that happens within it.
|
||||
* Returns an error if it throws, otherwise null.
|
||||
*
|
||||
* @param {String} name of the guard to use for logging or debugging
|
||||
* @param {Function} func The function to invoke
|
||||
* @param {*} context The context to use when calling the function
|
||||
* @param {...*} args Arguments for function
|
||||
*/
|
||||
const ReactErrorUtils = {
|
||||
injection: {
|
||||
injectErrorUtils(injectedErrorUtils: Object) {
|
||||
|
@ -96,6 +87,15 @@ const ReactErrorUtils = {
|
|||
},
|
||||
},
|
||||
|
||||
/**
|
||||
* Call a function while guarding against errors that happens within it.
|
||||
* Returns an error if it throws, otherwise null.
|
||||
*
|
||||
* @param {String} name of the guard to use for logging or debugging
|
||||
* @param {Function} func The function to invoke
|
||||
* @param {*} context The context to use when calling the function
|
||||
* @param {...*} args Arguments for function
|
||||
*/
|
||||
invokeGuardedCallback: function<A, B, C, D, E, F, Context>(
|
||||
name: string | null,
|
||||
func: (a: A, b: B, c: C, d: D, e: E, f: F) => void,
|
||||
|
|
|
@ -19,6 +19,7 @@ var ReactFeatureFlags = {
|
|||
logTopLevelRenders: false,
|
||||
prepareNewChildrenBeforeUnmountInStack: true,
|
||||
disableNewFiberFeatures: false,
|
||||
enableAsyncSubtreeAPI: false,
|
||||
};
|
||||
|
||||
module.exports = ReactFeatureFlags;
|
||||
|
|
|
@ -28,7 +28,8 @@ function adler32(data: string): number {
|
|||
while (i < m) {
|
||||
var n = Math.min(i + 4096, m);
|
||||
for (; i < n; i += 4) {
|
||||
b += (a += data.charCodeAt(i)) +
|
||||
b +=
|
||||
(a += data.charCodeAt(i)) +
|
||||
(a += data.charCodeAt(i + 1)) +
|
||||
(a += data.charCodeAt(i + 2)) +
|
||||
(a += data.charCodeAt(i + 3));
|
||||
|
@ -37,11 +38,11 @@ function adler32(data: string): number {
|
|||
b %= MOD;
|
||||
}
|
||||
for (; i < l; i++) {
|
||||
b += (a += data.charCodeAt(i));
|
||||
b += a += data.charCodeAt(i);
|
||||
}
|
||||
a %= MOD;
|
||||
b %= MOD;
|
||||
return a | b << 16;
|
||||
return a | (b << 16);
|
||||
}
|
||||
|
||||
module.exports = adler32;
|
||||
|
|
|
@ -24,7 +24,8 @@ var getComponentName = require('getComponentName');
|
|||
import type {Fiber} from 'ReactFiber';
|
||||
|
||||
function describeComponentFrame(name, source: any, ownerName) {
|
||||
return '\n in ' +
|
||||
return (
|
||||
'\n in ' +
|
||||
(name || 'Unknown') +
|
||||
(source
|
||||
? ' (at ' +
|
||||
|
@ -32,7 +33,8 @@ function describeComponentFrame(name, source: any, ownerName) {
|
|||
':' +
|
||||
source.lineNumber +
|
||||
')'
|
||||
: ownerName ? ' (created by ' + ownerName + ')' : '');
|
||||
: ownerName ? ' (created by ' + ownerName + ')' : '')
|
||||
);
|
||||
}
|
||||
|
||||
function describeFiber(fiber: Fiber): string {
|
||||
|
|
|
@ -1,26 +0,0 @@
|
|||
/**
|
||||
* Copyright 2013-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 checkReactTypeSpec
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
var checkPropTypes = require('react/lib/checkPropTypes');
|
||||
var {getStackAddendum} = require('react/lib/ReactDebugCurrentFrame');
|
||||
|
||||
function checkReactTypeSpec(
|
||||
typeSpecs,
|
||||
values,
|
||||
location: string,
|
||||
componentName,
|
||||
) {
|
||||
checkPropTypes(typeSpecs, values, location, componentName, getStackAddendum);
|
||||
}
|
||||
|
||||
module.exports = checkReactTypeSpec;
|
|
@ -95,7 +95,7 @@ var addPoolingTo = function<T>(
|
|||
CopyConstructor: Class<T>,
|
||||
pooler: Pooler,
|
||||
): Class<T> & {
|
||||
getPooled /* arguments of the constructor */(): T,
|
||||
getPooled(): /* arguments of the constructor */ T,
|
||||
release(): void,
|
||||
} {
|
||||
// Casting as any so that flow ignores the actual implementation and trusts
|
||||
|
|
|
@ -14,9 +14,8 @@
|
|||
|
||||
// The Symbol used to tag the ReactElement type. If there is no native Symbol
|
||||
// nor polyfill, then a plain number is used for performance.
|
||||
var REACT_ELEMENT_TYPE = (typeof Symbol === 'function' &&
|
||||
Symbol.for &&
|
||||
Symbol.for('react.element')) ||
|
||||
var REACT_ELEMENT_TYPE =
|
||||
(typeof Symbol === 'function' && Symbol.for && Symbol.for('react.element')) ||
|
||||
0xeac7;
|
||||
|
||||
module.exports = REACT_ELEMENT_TYPE;
|
||||
|
|
|
@ -6,8 +6,8 @@
|
|||
* 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.
|
||||
*
|
||||
* @flow
|
||||
* @providesModule getComponentName
|
||||
* @flow
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
|
|
@ -31,7 +31,8 @@ var FAUX_ITERATOR_SYMBOL = '@@iterator'; // Before Symbol spec.
|
|||
* @return {?function}
|
||||
*/
|
||||
function getIteratorFn(maybeIterable: ?any): ?() => ?Iterator<*> {
|
||||
var iteratorFn = maybeIterable &&
|
||||
var iteratorFn =
|
||||
maybeIterable &&
|
||||
((ITERATOR_SYMBOL && maybeIterable[ITERATOR_SYMBOL]) ||
|
||||
maybeIterable[FAUX_ITERATOR_SYMBOL]);
|
||||
if (typeof iteratorFn === 'function') {
|
||||
|
|
|
@ -20,7 +20,8 @@
|
|||
function reactProdInvariant(code: string): void {
|
||||
var argCount = arguments.length - 1;
|
||||
|
||||
var message = 'Minified React error #' +
|
||||
var message =
|
||||
'Minified React error #' +
|
||||
code +
|
||||
'; visit ' +
|
||||
'http://facebook.github.io/react/docs/error-decoder.html?invariant=' +
|
||||
|
@ -30,7 +31,8 @@ function reactProdInvariant(code: string): void {
|
|||
message += '&args[]=' + encodeURIComponent(arguments[argIdx + 1]);
|
||||
}
|
||||
|
||||
message += ' for the full message or use the non-minified dev environment' +
|
||||
message +=
|
||||
' for the full message or use the non-minified dev environment' +
|
||||
' for full errors and additional helpful warnings.';
|
||||
|
||||
var error: Error & {framesToPop?: number} = new Error(message);
|
||||
|
|
|
@ -11,4 +11,4 @@
|
|||
|
||||
'use strict';
|
||||
|
||||
module.exports = require('react/lib/React');
|
||||
module.exports = require('react');
|
||||
|
|
|
@ -128,7 +128,7 @@
|
|||
"react-native": "local-cli/wrong-react-native.js"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": "16.0.0-alpha.6"
|
||||
"react": "16.0.0-alpha.12"
|
||||
},
|
||||
"dependencies": {
|
||||
"absolute-path": "^0.0.0",
|
||||
|
@ -162,7 +162,7 @@
|
|||
"denodeify": "^1.2.1",
|
||||
"errno": ">=0.1.1 <0.2.0-0",
|
||||
"event-target-shim": "^1.0.5",
|
||||
"fbjs": "~0.8.9",
|
||||
"fbjs": "0.8.12",
|
||||
"fbjs-scripts": "^0.7.0",
|
||||
"form-data": "^2.1.1",
|
||||
"fs-extra": "^1.0.0",
|
||||
|
@ -227,8 +227,8 @@
|
|||
"jest-repl": "19.0.2",
|
||||
"jest-runtime": "^19.0.3",
|
||||
"mock-fs": "^3.11.0",
|
||||
"react": "16.0.0-alpha.6",
|
||||
"react-test-renderer": "16.0.0-alpha.6",
|
||||
"react": "16.0.0-alpha.12",
|
||||
"react-test-renderer": "16.0.0-alpha.12",
|
||||
"shelljs": "0.6.0",
|
||||
"sinon": "^2.0.0-pre.2"
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче