diff --git a/Libraries/Renderer/REVISION b/Libraries/Renderer/REVISION index 9be2711e1c..86f9334dd7 100644 --- a/Libraries/Renderer/REVISION +++ b/Libraries/Renderer/REVISION @@ -1 +1 @@ -19f6fe170ce920d7183a5620f4e218334c8bac62 \ No newline at end of file +241c4467eef7c2a8858c96d5dfe4e8ef84c47bad \ No newline at end of file diff --git a/Libraries/Renderer/implementations/ReactFabric-dev.fb.js b/Libraries/Renderer/implementations/ReactFabric-dev.fb.js index 1b3fd6c211..70c02f1d84 100644 --- a/Libraries/Renderer/implementations/ReactFabric-dev.fb.js +++ b/Libraries/Renderer/implementations/ReactFabric-dev.fb.js @@ -687,14 +687,14 @@ var validateEventDispatches; var listenersLen = listenersIsArr ? dispatchListeners.length : dispatchListeners - ? 1 - : 0; + ? 1 + : 0; var instancesIsArr = Array.isArray(dispatchInstances); var instancesLen = instancesIsArr ? dispatchInstances.length : dispatchInstances - ? 1 - : 0; + ? 1 + : 0; if (instancesIsArr !== listenersIsArr || instancesLen !== listenersLen) { error("EventPluginUtils: Invalid `event`."); @@ -2262,10 +2262,10 @@ function setResponderAndExtractTransfer( var shouldSetEventType = isStartish(topLevelType) ? eventTypes.startShouldSetResponder : isMoveish(topLevelType) - ? eventTypes.moveShouldSetResponder - : topLevelType === TOP_SELECTION_CHANGE - ? eventTypes.selectionChangeShouldSetResponder - : eventTypes.scrollShouldSetResponder; // TODO: stop one short of the current responder. + ? eventTypes.moveShouldSetResponder + : topLevelType === TOP_SELECTION_CHANGE + ? eventTypes.selectionChangeShouldSetResponder + : eventTypes.scrollShouldSetResponder; // TODO: stop one short of the current responder. var bubbleShouldSetFrom = !responderInst ? targetInst @@ -2469,10 +2469,10 @@ var ResponderEventPlugin = { var incrementalTouch = isResponderTouchStart ? eventTypes.responderStart : isResponderTouchMove - ? eventTypes.responderMove - : isResponderTouchEnd - ? eventTypes.responderEnd - : null; + ? eventTypes.responderMove + : isResponderTouchEnd + ? eventTypes.responderEnd + : null; if (incrementalTouch) { var gesture = ResponderSyntheticEvent.getPooled( @@ -2496,8 +2496,8 @@ var ResponderEventPlugin = { var finalTouch = isResponderTerminate ? eventTypes.responderTerminate : isResponderRelease - ? eventTypes.responderRelease - : null; + ? eventTypes.responderRelease + : null; if (finalTouch) { var finalEvent = ResponderSyntheticEvent.getPooled( @@ -2632,7 +2632,8 @@ var warnAboutDefaultPropsOnFunctionComponents = false; var warnAboutStringRefs = false; var disableLegacyContext = false; var disableSchedulerTimeoutBasedOnReactExpirationTime = false; -var enableTrainModelFix = false; +var enableTrainModelFix = true; + // Only used in www builds. // Flow magic to verify the exports of this file match the original version. @@ -5561,7 +5562,7 @@ function is(x, y) { ); } -var is$1 = typeof Object.is === "function" ? Object.is : is; +var objectIs = typeof Object.is === "function" ? Object.is : is; var hasOwnProperty = Object.prototype.hasOwnProperty; /** @@ -5571,7 +5572,7 @@ var hasOwnProperty = Object.prototype.hasOwnProperty; */ function shallowEqual(objA, objB) { - if (is$1(objA, objB)) { + if (objectIs(objA, objB)) { return true; } @@ -5594,7 +5595,7 @@ function shallowEqual(objA, objB) { for (var i = 0; i < keysA.length; i++) { if ( !hasOwnProperty.call(objB, keysA[i]) || - !is$1(objA[keysA[i]], objB[keysA[i]]) + !objectIs(objA[keysA[i]], objB[keysA[i]]) ) { return false; } @@ -5911,13 +5912,18 @@ var ReactStrictModeWarnings = { ReactStrictModeWarnings.flushLegacyContextWarning = function() { pendingLegacyContextWarning.forEach(function(fiberArray, strictRoot) { + if (fiberArray.length === 0) { + return; + } + + var firstFiber = fiberArray[0]; var uniqueNames = new Set(); fiberArray.forEach(function(fiber) { uniqueNames.add(getComponentName(fiber.type) || "Component"); didWarnAboutLegacyContext.add(fiber.type); }); var sortedNames = setToSortedString(uniqueNames); - var strictRootComponentStack = getStackByFiberInDevAndProd(strictRoot); + var firstComponentStack = getStackByFiberInDevAndProd(firstFiber); error( "Legacy context API has been detected within a strict-mode tree." + @@ -5927,7 +5933,7 @@ var ReactStrictModeWarnings = { "\n\nLearn more about this warning here: https://fb.me/react-legacy-context" + "%s", sortedNames, - strictRootComponentStack + firstComponentStack ); }); }; @@ -6497,7 +6503,7 @@ function popProvider(providerFiber) { } } function calculateChangedBits(context, newValue, oldValue) { - if (is$1(oldValue, newValue)) { + if (objectIs(oldValue, newValue)) { // No change return 0; } else { @@ -8458,7 +8464,16 @@ function coerceRef(returnFiber, current$$1, element) { { // TODO: Clean this up once we turn on the string ref warning for // everyone, because the strict mode case will no longer be relevant - if (returnFiber.mode & StrictMode || warnAboutStringRefs) { + if ( + (returnFiber.mode & StrictMode || warnAboutStringRefs) && // We warn in ReactElement.js if owner and self are equal for string refs + // because these cannot be automatically converted to an arrow function + // using a codemod. Therefore, we don't have to warn about string refs again. + !( + element._owner && + element._self && + element._owner.stateNode !== element._self + ) + ) { var componentName = getComponentName(returnFiber.type) || "Component"; if (!didWarnAboutStringRefs[componentName]) { @@ -10320,20 +10335,12 @@ var currentlyRenderingFiber$1 = null; // Hooks are stored as a linked list on th // work-in-progress fiber. var currentHook = null; -var workInProgressHook = null; // Updates scheduled during render will trigger an immediate re-render at the -// end of the current pass. We can't store these updates on the normal queue, -// because if the work is aborted, they should be discarded. Because this is -// a relatively rare case, we also don't want to add an additional field to -// either the hook or queue object types. So we store them in a lazily create -// map of queue -> render-phase updates, which are discarded once the component -// completes without re-rendering. -// Whether an update was scheduled during the currently executing render pass. +var workInProgressHook = null; // Whether an update was scheduled at any point during the render phase. This +// does not get reset if we do another render pass; only when we're completely +// finished evaluating this component. This is an optimization so we know +// whether we need to clear render phase updates after a throw. -var didScheduleRenderPhaseUpdate = false; // Lazily created map of render-phase updates - -var renderPhaseUpdates = null; // Counter to prevent infinite loops. - -var numberOfReRenders = 0; +var didScheduleRenderPhaseUpdate = false; var RE_RENDER_LIMIT = 25; // In DEV, this is the name of the currently executing primitive hook var currentHookNameInDev = null; // In DEV, this list ensures that hooks are called in the same order between renders. @@ -10476,7 +10483,7 @@ function areHookInputsEqual(nextDeps, prevDeps) { } for (var i = 0; i < prevDeps.length && i < nextDeps.length; i++) { - if (is$1(nextDeps[i], prevDeps[i])) { + if (objectIs(nextDeps[i], prevDeps[i])) { continue; } @@ -10511,8 +10518,6 @@ function renderWithHooks( // currentHook = null; // workInProgressHook = null; // didScheduleRenderPhaseUpdate = false; - // renderPhaseUpdates = null; - // numberOfReRenders = 0; // TODO Warn if no hooks are used at all during mount, then some are used during update. // Currently we will identify the update render as a mount because memoizedState === null. // This is tricky because it's valid for certain types of components (e.g. React.lazy) @@ -10535,11 +10540,22 @@ function renderWithHooks( } } - var children = Component(props, secondArg); + var children = Component(props, secondArg); // Check if there was a render phase update + + if (workInProgress.expirationTime === renderExpirationTime$1) { + // Keep rendering in a loop for as long as render phase updates continue to + // be scheduled. Use a counter to prevent infinite loops. + var numberOfReRenders = 0; - if (didScheduleRenderPhaseUpdate) { do { - didScheduleRenderPhaseUpdate = false; + workInProgress.expirationTime = NoWork; + + if (!(numberOfReRenders < RE_RENDER_LIMIT)) { + throw Error( + "Too many re-renders. React limits the number of renders to prevent an infinite loop." + ); + } + numberOfReRenders += 1; { @@ -10557,12 +10573,9 @@ function renderWithHooks( hookTypesUpdateIndexDev = -1; } - ReactCurrentDispatcher$1.current = HooksDispatcherOnUpdateInDEV; + ReactCurrentDispatcher$1.current = HooksDispatcherOnRerenderInDEV; children = Component(props, secondArg); - } while (didScheduleRenderPhaseUpdate); - - renderPhaseUpdates = null; - numberOfReRenders = 0; + } while (workInProgress.expirationTime === renderExpirationTime$1); } // We can assume the previous dispatcher is always this one, since we set it // at the beginning of the render phase and there's no re-entrancy. @@ -10583,10 +10596,9 @@ function renderWithHooks( currentHookNameInDev = null; hookTypesDev = null; hookTypesUpdateIndexDev = -1; - } // These were reset above - // didScheduleRenderPhaseUpdate = false; - // renderPhaseUpdates = null; - // numberOfReRenders = 0; + } + + didScheduleRenderPhaseUpdate = false; if (!!didRenderTooFewHooks) { throw Error( @@ -10604,12 +10616,32 @@ function bailoutHooks(current, workInProgress, expirationTime) { current.expirationTime = NoWork; } } -function resetHooks() { +function resetHooksAfterThrow() { // We can assume the previous dispatcher is always this one, since we set it // at the beginning of the render phase and there's no re-entrancy. - ReactCurrentDispatcher$1.current = ContextOnlyDispatcher; // This is used to reset the state of this module when a component throws. - // It's also called inside mountIndeterminateComponent if we determine the - // component is a module-style component. + ReactCurrentDispatcher$1.current = ContextOnlyDispatcher; + + if (didScheduleRenderPhaseUpdate) { + // There were render phase updates. These are only valid for this render + // phase, which we are now aborting. Remove the updates from the queues so + // they do not persist to the next render. Do not remove updates from hooks + // that weren't processed. + // + // Only reset the updates from the queue if it has a clone. If it does + // not have a clone, that means it wasn't processed, and the updates were + // scheduled before we entered the render phase. + var hook = currentlyRenderingFiber$1.memoizedState; + + while (hook !== null) { + var queue = hook.queue; + + if (queue !== null) { + queue.pending = null; + } + + hook = hook.next; + } + } renderExpirationTime$1 = NoWork; currentlyRenderingFiber$1 = null; @@ -10623,8 +10655,6 @@ function resetHooks() { } didScheduleRenderPhaseUpdate = false; - renderPhaseUpdates = null; - numberOfReRenders = 0; } function mountWorkInProgressHook() { @@ -10714,6 +10744,7 @@ function createFunctionComponentUpdateQueue() { } function basicStateReducer(state, action) { + // $FlowFixMe: Flow doesn't like mixed types return typeof action === "function" ? action(state) : action; } @@ -10753,52 +10784,6 @@ function updateReducer(reducer, initialArg, init) { } queue.lastRenderedReducer = reducer; - - if (numberOfReRenders > 0) { - // This is a re-render. Apply the new render phase updates to the previous - // work-in-progress hook. - var _dispatch = queue.dispatch; - - if (renderPhaseUpdates !== null) { - // Render phase updates are stored in a map of queue -> linked list - var firstRenderPhaseUpdate = renderPhaseUpdates.get(queue); - - if (firstRenderPhaseUpdate !== undefined) { - renderPhaseUpdates.delete(queue); - var newState = hook.memoizedState; - var update = firstRenderPhaseUpdate; - - do { - // Process this render phase update. We don't have to check the - // priority because it will always be the same as the current - // render's. - var action = update.action; - newState = reducer(newState, action); - update = update.next; - } while (update !== null); // Mark that the fiber performed work, but only if the new state is - // different from the current state. - - if (!is$1(newState, hook.memoizedState)) { - markWorkInProgressReceivedUpdate(); - } - - hook.memoizedState = newState; // Don't persist the state accumulated from the render phase updates to - // the base state unless the queue is empty. - // TODO: Not sure if this is the desired semantics, but it's what we - // do for gDSFP. I can't remember why. - - if (hook.baseQueue === null) { - hook.baseState = newState; - } - - queue.lastRenderedState = newState; - return [newState, _dispatch]; - } - } - - return [hook.memoizedState, _dispatch]; - } - var current = currentHook; // The last rebase update that is NOT part of the base state. var baseQueue = current.baseQueue; // The last pending update that hasn't been processed yet. @@ -10823,31 +10808,31 @@ function updateReducer(reducer, initialArg, init) { if (baseQueue !== null) { // We have a queue to process. var first = baseQueue.next; - var _newState = current.baseState; + var newState = current.baseState; var newBaseState = null; var newBaseQueueFirst = null; var newBaseQueueLast = null; - var _update = first; + var update = first; do { - var updateExpirationTime = _update.expirationTime; + var updateExpirationTime = update.expirationTime; if (updateExpirationTime < renderExpirationTime$1) { // Priority is insufficient. Skip this update. If this is the first // skipped update, the previous update/state is the new base // update/state. var clone = { - expirationTime: _update.expirationTime, - suspenseConfig: _update.suspenseConfig, - action: _update.action, - eagerReducer: _update.eagerReducer, - eagerState: _update.eagerState, + expirationTime: update.expirationTime, + suspenseConfig: update.suspenseConfig, + action: update.action, + eagerReducer: update.eagerReducer, + eagerState: update.eagerState, next: null }; if (newBaseQueueLast === null) { newBaseQueueFirst = newBaseQueueLast = clone; - newBaseState = _newState; + newBaseState = newState; } else { newBaseQueueLast = newBaseQueueLast.next = clone; } // Update the remaining priority in the queue. @@ -10862,10 +10847,10 @@ function updateReducer(reducer, initialArg, init) { var _clone = { expirationTime: Sync, // This update is going to be committed so we never want uncommit it. - suspenseConfig: _update.suspenseConfig, - action: _update.action, - eagerReducer: _update.eagerReducer, - eagerState: _update.eagerState, + suspenseConfig: update.suspenseConfig, + action: update.action, + eagerReducer: update.eagerReducer, + eagerState: update.eagerState, next: null }; newBaseQueueLast = newBaseQueueLast.next = _clone; @@ -10878,47 +10863,100 @@ function updateReducer(reducer, initialArg, init) { markRenderEventTimeAndConfig( updateExpirationTime, - _update.suspenseConfig + update.suspenseConfig ); // Process this update. - if (_update.eagerReducer === reducer) { + if (update.eagerReducer === reducer) { // If this update was processed eagerly, and its reducer matches the // current reducer, we can use the eagerly computed state. - _newState = _update.eagerState; + newState = update.eagerState; } else { - var _action = _update.action; - _newState = reducer(_newState, _action); + var action = update.action; + newState = reducer(newState, action); } } - _update = _update.next; - } while (_update !== null && _update !== first); + update = update.next; + } while (update !== null && update !== first); if (newBaseQueueLast === null) { - newBaseState = _newState; + newBaseState = newState; } else { newBaseQueueLast.next = newBaseQueueFirst; } // Mark that the fiber performed work, but only if the new state is // different from the current state. - if (!is$1(_newState, hook.memoizedState)) { + if (!objectIs(newState, hook.memoizedState)) { markWorkInProgressReceivedUpdate(); } - hook.memoizedState = _newState; + hook.memoizedState = newState; hook.baseState = newBaseState; hook.baseQueue = newBaseQueueLast; - queue.lastRenderedState = _newState; + queue.lastRenderedState = newState; } var dispatch = queue.dispatch; return [hook.memoizedState, dispatch]; } +function rerenderReducer(reducer, initialArg, init) { + var hook = updateWorkInProgressHook(); + var queue = hook.queue; + + if (!(queue !== null)) { + throw Error( + "Should have a queue. This is likely a bug in React. Please file an issue." + ); + } + + queue.lastRenderedReducer = reducer; // This is a re-render. Apply the new render phase updates to the previous + // work-in-progress hook. + + var dispatch = queue.dispatch; + var lastRenderPhaseUpdate = queue.pending; + var newState = hook.memoizedState; + + if (lastRenderPhaseUpdate !== null) { + // The queue doesn't persist past this render pass. + queue.pending = null; + var firstRenderPhaseUpdate = lastRenderPhaseUpdate.next; + var update = firstRenderPhaseUpdate; + + do { + // Process this render phase update. We don't have to check the + // priority because it will always be the same as the current + // render's. + var action = update.action; + newState = reducer(newState, action); + update = update.next; + } while (update !== firstRenderPhaseUpdate); // Mark that the fiber performed work, but only if the new state is + // different from the current state. + + if (!objectIs(newState, hook.memoizedState)) { + markWorkInProgressReceivedUpdate(); + } + + hook.memoizedState = newState; // Don't persist the state accumulated from the render phase updates to + // the base state unless the queue is empty. + // TODO: Not sure if this is the desired semantics, but it's what we + // do for gDSFP. I can't remember why. + + if (hook.baseQueue === null) { + hook.baseState = newState; + } + + queue.lastRenderedState = newState; + } + + return [newState, dispatch]; +} + function mountState(initialState) { var hook = mountWorkInProgressHook(); if (typeof initialState === "function") { + // $FlowFixMe: Flow doesn't like mixed types initialState = initialState(); } @@ -10941,6 +10979,10 @@ function updateState(initialState) { return updateReducer(basicStateReducer, initialState); } +function rerenderState(initialState) { + return rerenderReducer(basicStateReducer, initialState); +} + function pushEffect(tag, create, destroy, deps) { var effect = { tag: tag, @@ -11240,6 +11282,27 @@ function updateDeferredValue(value, config) { return prevValue; } +function rerenderDeferredValue(value, config) { + var _rerenderState = rerenderState(value), + prevValue = _rerenderState[0], + setValue = _rerenderState[1]; + + updateEffect( + function() { + var previousConfig = ReactCurrentBatchConfig$1.suspense; + ReactCurrentBatchConfig$1.suspense = config === undefined ? null : config; + + try { + setValue(value); + } finally { + ReactCurrentBatchConfig$1.suspense = previousConfig; + } + }, + [value, config] + ); + return prevValue; +} + function startTransition(setPending, config, callback) { var priorityLevel = getCurrentPriorityLevel(); runWithPriority( @@ -11288,13 +11351,19 @@ function updateTransition(config) { return [start, isPending]; } -function dispatchAction(fiber, queue, action) { - if (!(numberOfReRenders < RE_RENDER_LIMIT)) { - throw Error( - "Too many re-renders. React limits the number of renders to prevent an infinite loop." - ); - } +function rerenderTransition(config) { + var _rerenderState2 = rerenderState(false), + isPending = _rerenderState2[0], + setPending = _rerenderState2[1]; + var start = updateCallback(startTransition.bind(null, setPending, config), [ + setPending, + config + ]); + return [start, isPending]; +} + +function dispatchAction(fiber, queue, action) { { if (typeof arguments[3] === "function") { error( @@ -11305,6 +11374,37 @@ function dispatchAction(fiber, queue, action) { } } + var currentTime = requestCurrentTimeForUpdate(); + var suspenseConfig = requestCurrentSuspenseConfig(); + var expirationTime = computeExpirationForFiber( + currentTime, + fiber, + suspenseConfig + ); + var update = { + expirationTime: expirationTime, + suspenseConfig: suspenseConfig, + action: action, + eagerReducer: null, + eagerState: null, + next: null + }; + + { + update.priority = getCurrentPriorityLevel(); + } // Append the update to the end of the list. + + var pending = queue.pending; + + if (pending === null) { + // This is the first update. Create a circular list. + update.next = update; + } else { + update.next = pending.next; + pending.next = update; + } + + queue.pending = update; var alternate = fiber.alternate; if ( @@ -11315,70 +11415,9 @@ function dispatchAction(fiber, queue, action) { // queue -> linked list of updates. After this render pass, we'll restart // and apply the stashed updates on top of the work-in-progress hook. didScheduleRenderPhaseUpdate = true; - var update = { - expirationTime: renderExpirationTime$1, - suspenseConfig: null, - action: action, - eagerReducer: null, - eagerState: null, - next: null - }; - - { - update.priority = getCurrentPriorityLevel(); - } - - if (renderPhaseUpdates === null) { - renderPhaseUpdates = new Map(); - } - - var firstRenderPhaseUpdate = renderPhaseUpdates.get(queue); - - if (firstRenderPhaseUpdate === undefined) { - renderPhaseUpdates.set(queue, update); - } else { - // Append the update to the end of the list. - var lastRenderPhaseUpdate = firstRenderPhaseUpdate; - - while (lastRenderPhaseUpdate.next !== null) { - lastRenderPhaseUpdate = lastRenderPhaseUpdate.next; - } - - lastRenderPhaseUpdate.next = update; - } + update.expirationTime = renderExpirationTime$1; + currentlyRenderingFiber$1.expirationTime = renderExpirationTime$1; } else { - var currentTime = requestCurrentTimeForUpdate(); - var suspenseConfig = requestCurrentSuspenseConfig(); - var expirationTime = computeExpirationForFiber( - currentTime, - fiber, - suspenseConfig - ); - var _update2 = { - expirationTime: expirationTime, - suspenseConfig: suspenseConfig, - action: action, - eagerReducer: null, - eagerState: null, - next: null - }; - - { - _update2.priority = getCurrentPriorityLevel(); - } // Append the update to the end of the list. - - var pending = queue.pending; - - if (pending === null) { - // This is the first update. Create a circular list. - _update2.next = _update2; - } else { - _update2.next = pending.next; - pending.next = _update2; - } - - queue.pending = _update2; - if ( fiber.expirationTime === NoWork && (alternate === null || alternate.expirationTime === NoWork) @@ -11403,10 +11442,10 @@ function dispatchAction(fiber, queue, action) { // time we enter the render phase, then the eager state can be used // without calling the reducer again. - _update2.eagerReducer = lastRenderedReducer; - _update2.eagerState = eagerState; + update.eagerReducer = lastRenderedReducer; + update.eagerState = eagerState; - if (is$1(eagerState, currentState)) { + if (objectIs(eagerState, currentState)) { // Fast path. We can bail out without scheduling React to re-render. // It's still possible that we'll need to rebase this update later, // if the component re-renders for a different reason and by that @@ -11454,8 +11493,10 @@ var ContextOnlyDispatcher = { var HooksDispatcherOnMountInDEV = null; var HooksDispatcherOnMountWithHookTypesInDEV = null; var HooksDispatcherOnUpdateInDEV = null; +var HooksDispatcherOnRerenderInDEV = null; var InvalidNestedHooksDispatcherOnMountInDEV = null; var InvalidNestedHooksDispatcherOnUpdateInDEV = null; +var InvalidNestedHooksDispatcherOnRerenderInDEV = null; { var warnInvalidContextAccess = function() { @@ -11754,6 +11795,97 @@ var InvalidNestedHooksDispatcherOnUpdateInDEV = null; return updateTransition(config); } }; + HooksDispatcherOnRerenderInDEV = { + readContext: function(context, observedBits) { + return readContext(context, observedBits); + }, + useCallback: function(callback, deps) { + currentHookNameInDev = "useCallback"; + updateHookTypesDev(); + return updateCallback(callback, deps); + }, + useContext: function(context, observedBits) { + currentHookNameInDev = "useContext"; + updateHookTypesDev(); + return readContext(context, observedBits); + }, + useEffect: function(create, deps) { + currentHookNameInDev = "useEffect"; + updateHookTypesDev(); + return updateEffect(create, deps); + }, + useImperativeHandle: function(ref, create, deps) { + currentHookNameInDev = "useImperativeHandle"; + updateHookTypesDev(); + return updateImperativeHandle(ref, create, deps); + }, + useLayoutEffect: function(create, deps) { + currentHookNameInDev = "useLayoutEffect"; + updateHookTypesDev(); + return updateLayoutEffect(create, deps); + }, + useMemo: function(create, deps) { + currentHookNameInDev = "useMemo"; + updateHookTypesDev(); + var prevDispatcher = ReactCurrentDispatcher$1.current; + ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnRerenderInDEV; + + try { + return updateMemo(create, deps); + } finally { + ReactCurrentDispatcher$1.current = prevDispatcher; + } + }, + useReducer: function(reducer, initialArg, init) { + currentHookNameInDev = "useReducer"; + updateHookTypesDev(); + var prevDispatcher = ReactCurrentDispatcher$1.current; + ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnRerenderInDEV; + + try { + return rerenderReducer(reducer, initialArg, init); + } finally { + ReactCurrentDispatcher$1.current = prevDispatcher; + } + }, + useRef: function(initialValue) { + currentHookNameInDev = "useRef"; + updateHookTypesDev(); + return updateRef(initialValue); + }, + useState: function(initialState) { + currentHookNameInDev = "useState"; + updateHookTypesDev(); + var prevDispatcher = ReactCurrentDispatcher$1.current; + ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnRerenderInDEV; + + try { + return rerenderState(initialState); + } finally { + ReactCurrentDispatcher$1.current = prevDispatcher; + } + }, + useDebugValue: function(value, formatterFn) { + currentHookNameInDev = "useDebugValue"; + updateHookTypesDev(); + return updateDebugValue(value, formatterFn); + }, + useResponder: function(responder, props) { + currentHookNameInDev = "useResponder"; + updateHookTypesDev(); + return createDeprecatedResponderListener(responder, props); + }, + useDeferredValue: function(value, config) { + currentHookNameInDev = "useDeferredValue"; + updateHookTypesDev(); + return rerenderDeferredValue(value, config); + }, + useTransition: function(config) { + currentHookNameInDev = "useTransition"; + updateHookTypesDev(); + return rerenderTransition(config); + } + }; InvalidNestedHooksDispatcherOnMountInDEV = { readContext: function(context, observedBits) { warnInvalidContextAccess(); @@ -11964,6 +12096,111 @@ var InvalidNestedHooksDispatcherOnUpdateInDEV = null; return updateTransition(config); } }; + InvalidNestedHooksDispatcherOnRerenderInDEV = { + readContext: function(context, observedBits) { + warnInvalidContextAccess(); + return readContext(context, observedBits); + }, + useCallback: function(callback, deps) { + currentHookNameInDev = "useCallback"; + warnInvalidHookAccess(); + updateHookTypesDev(); + return updateCallback(callback, deps); + }, + useContext: function(context, observedBits) { + currentHookNameInDev = "useContext"; + warnInvalidHookAccess(); + updateHookTypesDev(); + return readContext(context, observedBits); + }, + useEffect: function(create, deps) { + currentHookNameInDev = "useEffect"; + warnInvalidHookAccess(); + updateHookTypesDev(); + return updateEffect(create, deps); + }, + useImperativeHandle: function(ref, create, deps) { + currentHookNameInDev = "useImperativeHandle"; + warnInvalidHookAccess(); + updateHookTypesDev(); + return updateImperativeHandle(ref, create, deps); + }, + useLayoutEffect: function(create, deps) { + currentHookNameInDev = "useLayoutEffect"; + warnInvalidHookAccess(); + updateHookTypesDev(); + return updateLayoutEffect(create, deps); + }, + useMemo: function(create, deps) { + currentHookNameInDev = "useMemo"; + warnInvalidHookAccess(); + updateHookTypesDev(); + var prevDispatcher = ReactCurrentDispatcher$1.current; + ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV; + + try { + return updateMemo(create, deps); + } finally { + ReactCurrentDispatcher$1.current = prevDispatcher; + } + }, + useReducer: function(reducer, initialArg, init) { + currentHookNameInDev = "useReducer"; + warnInvalidHookAccess(); + updateHookTypesDev(); + var prevDispatcher = ReactCurrentDispatcher$1.current; + ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV; + + try { + return rerenderReducer(reducer, initialArg, init); + } finally { + ReactCurrentDispatcher$1.current = prevDispatcher; + } + }, + useRef: function(initialValue) { + currentHookNameInDev = "useRef"; + warnInvalidHookAccess(); + updateHookTypesDev(); + return updateRef(initialValue); + }, + useState: function(initialState) { + currentHookNameInDev = "useState"; + warnInvalidHookAccess(); + updateHookTypesDev(); + var prevDispatcher = ReactCurrentDispatcher$1.current; + ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV; + + try { + return rerenderState(initialState); + } finally { + ReactCurrentDispatcher$1.current = prevDispatcher; + } + }, + useDebugValue: function(value, formatterFn) { + currentHookNameInDev = "useDebugValue"; + warnInvalidHookAccess(); + updateHookTypesDev(); + return updateDebugValue(value, formatterFn); + }, + useResponder: function(responder, props) { + currentHookNameInDev = "useResponder"; + warnInvalidHookAccess(); + updateHookTypesDev(); + return createDeprecatedResponderListener(responder, props); + }, + useDeferredValue: function(value, config) { + currentHookNameInDev = "useDeferredValue"; + warnInvalidHookAccess(); + updateHookTypesDev(); + return rerenderDeferredValue(value, config); + }, + useTransition: function(config) { + currentHookNameInDev = "useTransition"; + warnInvalidHookAccess(); + updateHookTypesDev(); + return rerenderTransition(config); + } + }; } // CommonJS interop named imports. @@ -13696,7 +13933,8 @@ function mountIndeterminateComponent( workInProgress.tag = ClassComponent; // Throw out any hooks that were used. - resetHooks(); // Push context providers early to prevent context stack mismatches. + workInProgress.memoizedState = null; + workInProgress.updateQueue = null; // Push context providers early to prevent context stack mismatches. // During mounting we don't know the child context yet as the instance doesn't exist. // We will invalidate the child context in finishClassComponent() right after rendering. @@ -15724,17 +15962,16 @@ var emptyObject$2 = {}; function collectScopedNodes(node, fn, scopedNodes) { if (enableScopeAPI) { if (node.tag === HostComponent) { - var _type = node.type, + var type = node.type, memoizedProps = node.memoizedProps, stateNode = node.stateNode; - - var _instance = getPublicInstance(stateNode); + var instance = getPublicInstance(stateNode); if ( - _instance !== null && - fn(_type, memoizedProps || emptyObject$2, _instance) === true + instance !== null && + fn(type, memoizedProps || emptyObject$2, instance) === true ) { - scopedNodes.push(_instance); + scopedNodes.push(instance); } } @@ -15753,17 +15990,13 @@ function collectScopedNodes(node, fn, scopedNodes) { function collectFirstScopedNode(node, fn) { if (enableScopeAPI) { if (node.tag === HostComponent) { - var _type2 = node.type, + var type = node.type, memoizedProps = node.memoizedProps, stateNode = node.stateNode; + var instance = getPublicInstance(stateNode); - var _instance2 = getPublicInstance(stateNode); - - if ( - _instance2 !== null && - fn(_type2, memoizedProps, _instance2) === true - ) { - return _instance2; + if (instance !== null && fn(type, memoizedProps, instance) === true) { + return instance; } } @@ -15806,9 +16039,10 @@ function collectFirstScopedNodeFromChildren(startingChild, fn) { return null; } -function collectNearestScopeMethods(node, scope, childrenScopes) { - if (isValidScopeNode(node, scope)) { - childrenScopes.push(node.stateNode.methods); +function collectNearestContextValues(node, context, childContextValues) { + if (node.tag === ContextProvider && node.type._context === context) { + var contextValue = node.memoizedProps.value; + childContextValues.push(contextValue); } else { var child = node.child; @@ -15817,81 +16051,27 @@ function collectNearestScopeMethods(node, scope, childrenScopes) { } if (child !== null) { - collectNearestChildScopeMethods(child, scope, childrenScopes); + collectNearestChildContextValues(child, context, childContextValues); } } } -function collectNearestChildScopeMethods(startingChild, scope, childrenScopes) { +function collectNearestChildContextValues( + startingChild, + context, + childContextValues +) { var child = startingChild; while (child !== null) { - collectNearestScopeMethods(child, scope, childrenScopes); + collectNearestContextValues(child, context, childContextValues); child = child.sibling; } } -function isValidScopeNode(node, scope) { - return ( - node.tag === ScopeComponent && - node.type === scope && - node.stateNode !== null - ); -} - function createScopeMethods(scope, instance) { return { - getChildren: function() { - var currentFiber = instance.fiber; - var child = currentFiber.child; - var childrenScopes = []; - - if (child !== null) { - collectNearestChildScopeMethods(child, scope, childrenScopes); - } - - return childrenScopes.length === 0 ? null : childrenScopes; - }, - getChildrenFromRoot: function() { - var currentFiber = instance.fiber; - var node = currentFiber; - - while (node !== null) { - var parent = node.return; - - if (parent === null) { - break; - } - - node = parent; - - if (node.tag === ScopeComponent && node.type === scope) { - break; - } - } - - var childrenScopes = []; - collectNearestChildScopeMethods(node.child, scope, childrenScopes); - return childrenScopes.length === 0 ? null : childrenScopes; - }, - getParent: function() { - var node = instance.fiber.return; - - while (node !== null) { - if (node.tag === ScopeComponent && node.type === scope) { - return node.stateNode.methods; - } - - node = node.return; - } - - return null; - }, - getProps: function() { - var currentFiber = instance.fiber; - return currentFiber.memoizedProps; - }, - queryAllNodes: function(fn) { + DO_NOT_USE_queryAllNodes: function(fn) { var currentFiber = instance.fiber; var child = currentFiber.child; var scopedNodes = []; @@ -15902,7 +16082,7 @@ function createScopeMethods(scope, instance) { return scopedNodes.length === 0 ? null : scopedNodes; }, - queryFirstNode: function(fn) { + DO_NOT_USE_queryFirstNode: function(fn) { var currentFiber = instance.fiber; var child = currentFiber.child; @@ -15928,6 +16108,17 @@ function createScopeMethods(scope, instance) { } return false; + }, + getChildContextValues: function(context) { + var currentFiber = instance.fiber; + var child = currentFiber.child; + var childContextValues = []; + + if (child !== null) { + collectNearestChildContextValues(child, context, childContextValues); + } + + return childContextValues; } }; } @@ -20326,7 +20517,7 @@ function handleError(root, thrownValue) { try { // Reset module-level state that was set during the render phase. resetContextDependencies(); - resetHooks(); + resetHooksAfterThrow(); resetCurrentFiber(); if (workInProgress === null || workInProgress.return === null) { @@ -21492,16 +21683,16 @@ function jnd(timeElapsed) { return timeElapsed < 120 ? 120 : timeElapsed < 480 - ? 480 - : timeElapsed < 1080 - ? 1080 - : timeElapsed < 1920 - ? 1920 - : timeElapsed < 3000 - ? 3000 - : timeElapsed < 4320 - ? 4320 - : ceil(timeElapsed / 1960) * 1960; + ? 480 + : timeElapsed < 1080 + ? 1080 + : timeElapsed < 1920 + ? 1920 + : timeElapsed < 3000 + ? 3000 + : timeElapsed < 4320 + ? 4320 + : ceil(timeElapsed / 1960) * 1960; } function computeMsUntilSuspenseLoadingDelay( @@ -21668,7 +21859,7 @@ if (true && replayFailedUnitOfWorkWithInvokeGuardedCallback) { // corresponding changes there. resetContextDependencies(); - resetHooks(); // Don't reset current debug fiber, since we're about to work on the + resetHooksAfterThrow(); // Don't reset current debug fiber, since we're about to work on the // same fiber again. // Unwind the failed stack frame @@ -23417,7 +23608,7 @@ function createPortal( // TODO: this is special because it gets imported during build. -var ReactVersion = "16.12.0-experimental-19f6fe170"; +var ReactVersion = "16.12.0-experimental-241c4467e"; var NativeMethodsMixin = function(findNodeHandle, findHostInstance) { /** @@ -24266,7 +24457,12 @@ var ReactFabric = { updateContainer(element, root, null, callback); return getPublicRootInstance(root); }, + // Deprecated - this function is being renamed to stopSurface, use that instead. + // TODO (T47576999): Delete this once it's no longer called from native code. unmountComponentAtNode: function(containerTag) { + this.stopSurface(containerTag); + }, + stopSurface: function(containerTag) { var root = roots.get(containerTag); if (root) { diff --git a/Libraries/Renderer/implementations/ReactFabric-dev.js b/Libraries/Renderer/implementations/ReactFabric-dev.js index 398cab778a..66cdea5d19 100644 --- a/Libraries/Renderer/implementations/ReactFabric-dev.js +++ b/Libraries/Renderer/implementations/ReactFabric-dev.js @@ -688,14 +688,14 @@ var validateEventDispatches; var listenersLen = listenersIsArr ? dispatchListeners.length : dispatchListeners - ? 1 - : 0; + ? 1 + : 0; var instancesIsArr = Array.isArray(dispatchInstances); var instancesLen = instancesIsArr ? dispatchInstances.length : dispatchInstances - ? 1 - : 0; + ? 1 + : 0; if (instancesIsArr !== listenersIsArr || instancesLen !== listenersLen) { error("EventPluginUtils: Invalid `event`."); @@ -2263,10 +2263,10 @@ function setResponderAndExtractTransfer( var shouldSetEventType = isStartish(topLevelType) ? eventTypes.startShouldSetResponder : isMoveish(topLevelType) - ? eventTypes.moveShouldSetResponder - : topLevelType === TOP_SELECTION_CHANGE - ? eventTypes.selectionChangeShouldSetResponder - : eventTypes.scrollShouldSetResponder; // TODO: stop one short of the current responder. + ? eventTypes.moveShouldSetResponder + : topLevelType === TOP_SELECTION_CHANGE + ? eventTypes.selectionChangeShouldSetResponder + : eventTypes.scrollShouldSetResponder; // TODO: stop one short of the current responder. var bubbleShouldSetFrom = !responderInst ? targetInst @@ -2470,10 +2470,10 @@ var ResponderEventPlugin = { var incrementalTouch = isResponderTouchStart ? eventTypes.responderStart : isResponderTouchMove - ? eventTypes.responderMove - : isResponderTouchEnd - ? eventTypes.responderEnd - : null; + ? eventTypes.responderMove + : isResponderTouchEnd + ? eventTypes.responderEnd + : null; if (incrementalTouch) { var gesture = ResponderSyntheticEvent.getPooled( @@ -2497,8 +2497,8 @@ var ResponderEventPlugin = { var finalTouch = isResponderTerminate ? eventTypes.responderTerminate : isResponderRelease - ? eventTypes.responderRelease - : null; + ? eventTypes.responderRelease + : null; if (finalTouch) { var finalEvent = ResponderSyntheticEvent.getPooled( @@ -2628,9 +2628,11 @@ var warnAboutDefaultPropsOnFunctionComponents = false; var warnAboutStringRefs = false; var disableLegacyContext = false; var disableSchedulerTimeoutBasedOnReactExpirationTime = false; -var enableTrainModelFix = false; +var enableTrainModelFix = true; -var enableNativeTargetAsInstance = false; // Only used in www builds. +var enableNativeTargetAsInstance = false; + +// Only used in www builds. // Flow magic to verify the exports of this file match the original version. @@ -5558,7 +5560,7 @@ function is(x, y) { ); } -var is$1 = typeof Object.is === "function" ? Object.is : is; +var objectIs = typeof Object.is === "function" ? Object.is : is; var hasOwnProperty = Object.prototype.hasOwnProperty; /** @@ -5568,7 +5570,7 @@ var hasOwnProperty = Object.prototype.hasOwnProperty; */ function shallowEqual(objA, objB) { - if (is$1(objA, objB)) { + if (objectIs(objA, objB)) { return true; } @@ -5591,7 +5593,7 @@ function shallowEqual(objA, objB) { for (var i = 0; i < keysA.length; i++) { if ( !hasOwnProperty.call(objB, keysA[i]) || - !is$1(objA[keysA[i]], objB[keysA[i]]) + !objectIs(objA[keysA[i]], objB[keysA[i]]) ) { return false; } @@ -5908,13 +5910,18 @@ var ReactStrictModeWarnings = { ReactStrictModeWarnings.flushLegacyContextWarning = function() { pendingLegacyContextWarning.forEach(function(fiberArray, strictRoot) { + if (fiberArray.length === 0) { + return; + } + + var firstFiber = fiberArray[0]; var uniqueNames = new Set(); fiberArray.forEach(function(fiber) { uniqueNames.add(getComponentName(fiber.type) || "Component"); didWarnAboutLegacyContext.add(fiber.type); }); var sortedNames = setToSortedString(uniqueNames); - var strictRootComponentStack = getStackByFiberInDevAndProd(strictRoot); + var firstComponentStack = getStackByFiberInDevAndProd(firstFiber); error( "Legacy context API has been detected within a strict-mode tree." + @@ -5924,7 +5931,7 @@ var ReactStrictModeWarnings = { "\n\nLearn more about this warning here: https://fb.me/react-legacy-context" + "%s", sortedNames, - strictRootComponentStack + firstComponentStack ); }); }; @@ -6494,7 +6501,7 @@ function popProvider(providerFiber) { } } function calculateChangedBits(context, newValue, oldValue) { - if (is$1(oldValue, newValue)) { + if (objectIs(oldValue, newValue)) { // No change return 0; } else { @@ -8455,7 +8462,16 @@ function coerceRef(returnFiber, current$$1, element) { { // TODO: Clean this up once we turn on the string ref warning for // everyone, because the strict mode case will no longer be relevant - if (returnFiber.mode & StrictMode || warnAboutStringRefs) { + if ( + (returnFiber.mode & StrictMode || warnAboutStringRefs) && // We warn in ReactElement.js if owner and self are equal for string refs + // because these cannot be automatically converted to an arrow function + // using a codemod. Therefore, we don't have to warn about string refs again. + !( + element._owner && + element._self && + element._owner.stateNode !== element._self + ) + ) { var componentName = getComponentName(returnFiber.type) || "Component"; if (!didWarnAboutStringRefs[componentName]) { @@ -10317,20 +10333,12 @@ var currentlyRenderingFiber$1 = null; // Hooks are stored as a linked list on th // work-in-progress fiber. var currentHook = null; -var workInProgressHook = null; // Updates scheduled during render will trigger an immediate re-render at the -// end of the current pass. We can't store these updates on the normal queue, -// because if the work is aborted, they should be discarded. Because this is -// a relatively rare case, we also don't want to add an additional field to -// either the hook or queue object types. So we store them in a lazily create -// map of queue -> render-phase updates, which are discarded once the component -// completes without re-rendering. -// Whether an update was scheduled during the currently executing render pass. +var workInProgressHook = null; // Whether an update was scheduled at any point during the render phase. This +// does not get reset if we do another render pass; only when we're completely +// finished evaluating this component. This is an optimization so we know +// whether we need to clear render phase updates after a throw. -var didScheduleRenderPhaseUpdate = false; // Lazily created map of render-phase updates - -var renderPhaseUpdates = null; // Counter to prevent infinite loops. - -var numberOfReRenders = 0; +var didScheduleRenderPhaseUpdate = false; var RE_RENDER_LIMIT = 25; // In DEV, this is the name of the currently executing primitive hook var currentHookNameInDev = null; // In DEV, this list ensures that hooks are called in the same order between renders. @@ -10473,7 +10481,7 @@ function areHookInputsEqual(nextDeps, prevDeps) { } for (var i = 0; i < prevDeps.length && i < nextDeps.length; i++) { - if (is$1(nextDeps[i], prevDeps[i])) { + if (objectIs(nextDeps[i], prevDeps[i])) { continue; } @@ -10508,8 +10516,6 @@ function renderWithHooks( // currentHook = null; // workInProgressHook = null; // didScheduleRenderPhaseUpdate = false; - // renderPhaseUpdates = null; - // numberOfReRenders = 0; // TODO Warn if no hooks are used at all during mount, then some are used during update. // Currently we will identify the update render as a mount because memoizedState === null. // This is tricky because it's valid for certain types of components (e.g. React.lazy) @@ -10532,11 +10538,22 @@ function renderWithHooks( } } - var children = Component(props, secondArg); + var children = Component(props, secondArg); // Check if there was a render phase update + + if (workInProgress.expirationTime === renderExpirationTime$1) { + // Keep rendering in a loop for as long as render phase updates continue to + // be scheduled. Use a counter to prevent infinite loops. + var numberOfReRenders = 0; - if (didScheduleRenderPhaseUpdate) { do { - didScheduleRenderPhaseUpdate = false; + workInProgress.expirationTime = NoWork; + + if (!(numberOfReRenders < RE_RENDER_LIMIT)) { + throw Error( + "Too many re-renders. React limits the number of renders to prevent an infinite loop." + ); + } + numberOfReRenders += 1; { @@ -10554,12 +10571,9 @@ function renderWithHooks( hookTypesUpdateIndexDev = -1; } - ReactCurrentDispatcher$1.current = HooksDispatcherOnUpdateInDEV; + ReactCurrentDispatcher$1.current = HooksDispatcherOnRerenderInDEV; children = Component(props, secondArg); - } while (didScheduleRenderPhaseUpdate); - - renderPhaseUpdates = null; - numberOfReRenders = 0; + } while (workInProgress.expirationTime === renderExpirationTime$1); } // We can assume the previous dispatcher is always this one, since we set it // at the beginning of the render phase and there's no re-entrancy. @@ -10580,10 +10594,9 @@ function renderWithHooks( currentHookNameInDev = null; hookTypesDev = null; hookTypesUpdateIndexDev = -1; - } // These were reset above - // didScheduleRenderPhaseUpdate = false; - // renderPhaseUpdates = null; - // numberOfReRenders = 0; + } + + didScheduleRenderPhaseUpdate = false; if (!!didRenderTooFewHooks) { throw Error( @@ -10601,12 +10614,32 @@ function bailoutHooks(current, workInProgress, expirationTime) { current.expirationTime = NoWork; } } -function resetHooks() { +function resetHooksAfterThrow() { // We can assume the previous dispatcher is always this one, since we set it // at the beginning of the render phase and there's no re-entrancy. - ReactCurrentDispatcher$1.current = ContextOnlyDispatcher; // This is used to reset the state of this module when a component throws. - // It's also called inside mountIndeterminateComponent if we determine the - // component is a module-style component. + ReactCurrentDispatcher$1.current = ContextOnlyDispatcher; + + if (didScheduleRenderPhaseUpdate) { + // There were render phase updates. These are only valid for this render + // phase, which we are now aborting. Remove the updates from the queues so + // they do not persist to the next render. Do not remove updates from hooks + // that weren't processed. + // + // Only reset the updates from the queue if it has a clone. If it does + // not have a clone, that means it wasn't processed, and the updates were + // scheduled before we entered the render phase. + var hook = currentlyRenderingFiber$1.memoizedState; + + while (hook !== null) { + var queue = hook.queue; + + if (queue !== null) { + queue.pending = null; + } + + hook = hook.next; + } + } renderExpirationTime$1 = NoWork; currentlyRenderingFiber$1 = null; @@ -10620,8 +10653,6 @@ function resetHooks() { } didScheduleRenderPhaseUpdate = false; - renderPhaseUpdates = null; - numberOfReRenders = 0; } function mountWorkInProgressHook() { @@ -10711,6 +10742,7 @@ function createFunctionComponentUpdateQueue() { } function basicStateReducer(state, action) { + // $FlowFixMe: Flow doesn't like mixed types return typeof action === "function" ? action(state) : action; } @@ -10750,52 +10782,6 @@ function updateReducer(reducer, initialArg, init) { } queue.lastRenderedReducer = reducer; - - if (numberOfReRenders > 0) { - // This is a re-render. Apply the new render phase updates to the previous - // work-in-progress hook. - var _dispatch = queue.dispatch; - - if (renderPhaseUpdates !== null) { - // Render phase updates are stored in a map of queue -> linked list - var firstRenderPhaseUpdate = renderPhaseUpdates.get(queue); - - if (firstRenderPhaseUpdate !== undefined) { - renderPhaseUpdates.delete(queue); - var newState = hook.memoizedState; - var update = firstRenderPhaseUpdate; - - do { - // Process this render phase update. We don't have to check the - // priority because it will always be the same as the current - // render's. - var action = update.action; - newState = reducer(newState, action); - update = update.next; - } while (update !== null); // Mark that the fiber performed work, but only if the new state is - // different from the current state. - - if (!is$1(newState, hook.memoizedState)) { - markWorkInProgressReceivedUpdate(); - } - - hook.memoizedState = newState; // Don't persist the state accumulated from the render phase updates to - // the base state unless the queue is empty. - // TODO: Not sure if this is the desired semantics, but it's what we - // do for gDSFP. I can't remember why. - - if (hook.baseQueue === null) { - hook.baseState = newState; - } - - queue.lastRenderedState = newState; - return [newState, _dispatch]; - } - } - - return [hook.memoizedState, _dispatch]; - } - var current = currentHook; // The last rebase update that is NOT part of the base state. var baseQueue = current.baseQueue; // The last pending update that hasn't been processed yet. @@ -10820,31 +10806,31 @@ function updateReducer(reducer, initialArg, init) { if (baseQueue !== null) { // We have a queue to process. var first = baseQueue.next; - var _newState = current.baseState; + var newState = current.baseState; var newBaseState = null; var newBaseQueueFirst = null; var newBaseQueueLast = null; - var _update = first; + var update = first; do { - var updateExpirationTime = _update.expirationTime; + var updateExpirationTime = update.expirationTime; if (updateExpirationTime < renderExpirationTime$1) { // Priority is insufficient. Skip this update. If this is the first // skipped update, the previous update/state is the new base // update/state. var clone = { - expirationTime: _update.expirationTime, - suspenseConfig: _update.suspenseConfig, - action: _update.action, - eagerReducer: _update.eagerReducer, - eagerState: _update.eagerState, + expirationTime: update.expirationTime, + suspenseConfig: update.suspenseConfig, + action: update.action, + eagerReducer: update.eagerReducer, + eagerState: update.eagerState, next: null }; if (newBaseQueueLast === null) { newBaseQueueFirst = newBaseQueueLast = clone; - newBaseState = _newState; + newBaseState = newState; } else { newBaseQueueLast = newBaseQueueLast.next = clone; } // Update the remaining priority in the queue. @@ -10859,10 +10845,10 @@ function updateReducer(reducer, initialArg, init) { var _clone = { expirationTime: Sync, // This update is going to be committed so we never want uncommit it. - suspenseConfig: _update.suspenseConfig, - action: _update.action, - eagerReducer: _update.eagerReducer, - eagerState: _update.eagerState, + suspenseConfig: update.suspenseConfig, + action: update.action, + eagerReducer: update.eagerReducer, + eagerState: update.eagerState, next: null }; newBaseQueueLast = newBaseQueueLast.next = _clone; @@ -10875,47 +10861,100 @@ function updateReducer(reducer, initialArg, init) { markRenderEventTimeAndConfig( updateExpirationTime, - _update.suspenseConfig + update.suspenseConfig ); // Process this update. - if (_update.eagerReducer === reducer) { + if (update.eagerReducer === reducer) { // If this update was processed eagerly, and its reducer matches the // current reducer, we can use the eagerly computed state. - _newState = _update.eagerState; + newState = update.eagerState; } else { - var _action = _update.action; - _newState = reducer(_newState, _action); + var action = update.action; + newState = reducer(newState, action); } } - _update = _update.next; - } while (_update !== null && _update !== first); + update = update.next; + } while (update !== null && update !== first); if (newBaseQueueLast === null) { - newBaseState = _newState; + newBaseState = newState; } else { newBaseQueueLast.next = newBaseQueueFirst; } // Mark that the fiber performed work, but only if the new state is // different from the current state. - if (!is$1(_newState, hook.memoizedState)) { + if (!objectIs(newState, hook.memoizedState)) { markWorkInProgressReceivedUpdate(); } - hook.memoizedState = _newState; + hook.memoizedState = newState; hook.baseState = newBaseState; hook.baseQueue = newBaseQueueLast; - queue.lastRenderedState = _newState; + queue.lastRenderedState = newState; } var dispatch = queue.dispatch; return [hook.memoizedState, dispatch]; } +function rerenderReducer(reducer, initialArg, init) { + var hook = updateWorkInProgressHook(); + var queue = hook.queue; + + if (!(queue !== null)) { + throw Error( + "Should have a queue. This is likely a bug in React. Please file an issue." + ); + } + + queue.lastRenderedReducer = reducer; // This is a re-render. Apply the new render phase updates to the previous + // work-in-progress hook. + + var dispatch = queue.dispatch; + var lastRenderPhaseUpdate = queue.pending; + var newState = hook.memoizedState; + + if (lastRenderPhaseUpdate !== null) { + // The queue doesn't persist past this render pass. + queue.pending = null; + var firstRenderPhaseUpdate = lastRenderPhaseUpdate.next; + var update = firstRenderPhaseUpdate; + + do { + // Process this render phase update. We don't have to check the + // priority because it will always be the same as the current + // render's. + var action = update.action; + newState = reducer(newState, action); + update = update.next; + } while (update !== firstRenderPhaseUpdate); // Mark that the fiber performed work, but only if the new state is + // different from the current state. + + if (!objectIs(newState, hook.memoizedState)) { + markWorkInProgressReceivedUpdate(); + } + + hook.memoizedState = newState; // Don't persist the state accumulated from the render phase updates to + // the base state unless the queue is empty. + // TODO: Not sure if this is the desired semantics, but it's what we + // do for gDSFP. I can't remember why. + + if (hook.baseQueue === null) { + hook.baseState = newState; + } + + queue.lastRenderedState = newState; + } + + return [newState, dispatch]; +} + function mountState(initialState) { var hook = mountWorkInProgressHook(); if (typeof initialState === "function") { + // $FlowFixMe: Flow doesn't like mixed types initialState = initialState(); } @@ -10938,6 +10977,10 @@ function updateState(initialState) { return updateReducer(basicStateReducer, initialState); } +function rerenderState(initialState) { + return rerenderReducer(basicStateReducer, initialState); +} + function pushEffect(tag, create, destroy, deps) { var effect = { tag: tag, @@ -11237,6 +11280,27 @@ function updateDeferredValue(value, config) { return prevValue; } +function rerenderDeferredValue(value, config) { + var _rerenderState = rerenderState(value), + prevValue = _rerenderState[0], + setValue = _rerenderState[1]; + + updateEffect( + function() { + var previousConfig = ReactCurrentBatchConfig$1.suspense; + ReactCurrentBatchConfig$1.suspense = config === undefined ? null : config; + + try { + setValue(value); + } finally { + ReactCurrentBatchConfig$1.suspense = previousConfig; + } + }, + [value, config] + ); + return prevValue; +} + function startTransition(setPending, config, callback) { var priorityLevel = getCurrentPriorityLevel(); runWithPriority( @@ -11285,13 +11349,19 @@ function updateTransition(config) { return [start, isPending]; } -function dispatchAction(fiber, queue, action) { - if (!(numberOfReRenders < RE_RENDER_LIMIT)) { - throw Error( - "Too many re-renders. React limits the number of renders to prevent an infinite loop." - ); - } +function rerenderTransition(config) { + var _rerenderState2 = rerenderState(false), + isPending = _rerenderState2[0], + setPending = _rerenderState2[1]; + var start = updateCallback(startTransition.bind(null, setPending, config), [ + setPending, + config + ]); + return [start, isPending]; +} + +function dispatchAction(fiber, queue, action) { { if (typeof arguments[3] === "function") { error( @@ -11302,6 +11372,37 @@ function dispatchAction(fiber, queue, action) { } } + var currentTime = requestCurrentTimeForUpdate(); + var suspenseConfig = requestCurrentSuspenseConfig(); + var expirationTime = computeExpirationForFiber( + currentTime, + fiber, + suspenseConfig + ); + var update = { + expirationTime: expirationTime, + suspenseConfig: suspenseConfig, + action: action, + eagerReducer: null, + eagerState: null, + next: null + }; + + { + update.priority = getCurrentPriorityLevel(); + } // Append the update to the end of the list. + + var pending = queue.pending; + + if (pending === null) { + // This is the first update. Create a circular list. + update.next = update; + } else { + update.next = pending.next; + pending.next = update; + } + + queue.pending = update; var alternate = fiber.alternate; if ( @@ -11312,70 +11413,9 @@ function dispatchAction(fiber, queue, action) { // queue -> linked list of updates. After this render pass, we'll restart // and apply the stashed updates on top of the work-in-progress hook. didScheduleRenderPhaseUpdate = true; - var update = { - expirationTime: renderExpirationTime$1, - suspenseConfig: null, - action: action, - eagerReducer: null, - eagerState: null, - next: null - }; - - { - update.priority = getCurrentPriorityLevel(); - } - - if (renderPhaseUpdates === null) { - renderPhaseUpdates = new Map(); - } - - var firstRenderPhaseUpdate = renderPhaseUpdates.get(queue); - - if (firstRenderPhaseUpdate === undefined) { - renderPhaseUpdates.set(queue, update); - } else { - // Append the update to the end of the list. - var lastRenderPhaseUpdate = firstRenderPhaseUpdate; - - while (lastRenderPhaseUpdate.next !== null) { - lastRenderPhaseUpdate = lastRenderPhaseUpdate.next; - } - - lastRenderPhaseUpdate.next = update; - } + update.expirationTime = renderExpirationTime$1; + currentlyRenderingFiber$1.expirationTime = renderExpirationTime$1; } else { - var currentTime = requestCurrentTimeForUpdate(); - var suspenseConfig = requestCurrentSuspenseConfig(); - var expirationTime = computeExpirationForFiber( - currentTime, - fiber, - suspenseConfig - ); - var _update2 = { - expirationTime: expirationTime, - suspenseConfig: suspenseConfig, - action: action, - eagerReducer: null, - eagerState: null, - next: null - }; - - { - _update2.priority = getCurrentPriorityLevel(); - } // Append the update to the end of the list. - - var pending = queue.pending; - - if (pending === null) { - // This is the first update. Create a circular list. - _update2.next = _update2; - } else { - _update2.next = pending.next; - pending.next = _update2; - } - - queue.pending = _update2; - if ( fiber.expirationTime === NoWork && (alternate === null || alternate.expirationTime === NoWork) @@ -11400,10 +11440,10 @@ function dispatchAction(fiber, queue, action) { // time we enter the render phase, then the eager state can be used // without calling the reducer again. - _update2.eagerReducer = lastRenderedReducer; - _update2.eagerState = eagerState; + update.eagerReducer = lastRenderedReducer; + update.eagerState = eagerState; - if (is$1(eagerState, currentState)) { + if (objectIs(eagerState, currentState)) { // Fast path. We can bail out without scheduling React to re-render. // It's still possible that we'll need to rebase this update later, // if the component re-renders for a different reason and by that @@ -11451,8 +11491,10 @@ var ContextOnlyDispatcher = { var HooksDispatcherOnMountInDEV = null; var HooksDispatcherOnMountWithHookTypesInDEV = null; var HooksDispatcherOnUpdateInDEV = null; +var HooksDispatcherOnRerenderInDEV = null; var InvalidNestedHooksDispatcherOnMountInDEV = null; var InvalidNestedHooksDispatcherOnUpdateInDEV = null; +var InvalidNestedHooksDispatcherOnRerenderInDEV = null; { var warnInvalidContextAccess = function() { @@ -11751,6 +11793,97 @@ var InvalidNestedHooksDispatcherOnUpdateInDEV = null; return updateTransition(config); } }; + HooksDispatcherOnRerenderInDEV = { + readContext: function(context, observedBits) { + return readContext(context, observedBits); + }, + useCallback: function(callback, deps) { + currentHookNameInDev = "useCallback"; + updateHookTypesDev(); + return updateCallback(callback, deps); + }, + useContext: function(context, observedBits) { + currentHookNameInDev = "useContext"; + updateHookTypesDev(); + return readContext(context, observedBits); + }, + useEffect: function(create, deps) { + currentHookNameInDev = "useEffect"; + updateHookTypesDev(); + return updateEffect(create, deps); + }, + useImperativeHandle: function(ref, create, deps) { + currentHookNameInDev = "useImperativeHandle"; + updateHookTypesDev(); + return updateImperativeHandle(ref, create, deps); + }, + useLayoutEffect: function(create, deps) { + currentHookNameInDev = "useLayoutEffect"; + updateHookTypesDev(); + return updateLayoutEffect(create, deps); + }, + useMemo: function(create, deps) { + currentHookNameInDev = "useMemo"; + updateHookTypesDev(); + var prevDispatcher = ReactCurrentDispatcher$1.current; + ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnRerenderInDEV; + + try { + return updateMemo(create, deps); + } finally { + ReactCurrentDispatcher$1.current = prevDispatcher; + } + }, + useReducer: function(reducer, initialArg, init) { + currentHookNameInDev = "useReducer"; + updateHookTypesDev(); + var prevDispatcher = ReactCurrentDispatcher$1.current; + ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnRerenderInDEV; + + try { + return rerenderReducer(reducer, initialArg, init); + } finally { + ReactCurrentDispatcher$1.current = prevDispatcher; + } + }, + useRef: function(initialValue) { + currentHookNameInDev = "useRef"; + updateHookTypesDev(); + return updateRef(initialValue); + }, + useState: function(initialState) { + currentHookNameInDev = "useState"; + updateHookTypesDev(); + var prevDispatcher = ReactCurrentDispatcher$1.current; + ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnRerenderInDEV; + + try { + return rerenderState(initialState); + } finally { + ReactCurrentDispatcher$1.current = prevDispatcher; + } + }, + useDebugValue: function(value, formatterFn) { + currentHookNameInDev = "useDebugValue"; + updateHookTypesDev(); + return updateDebugValue(value, formatterFn); + }, + useResponder: function(responder, props) { + currentHookNameInDev = "useResponder"; + updateHookTypesDev(); + return createDeprecatedResponderListener(responder, props); + }, + useDeferredValue: function(value, config) { + currentHookNameInDev = "useDeferredValue"; + updateHookTypesDev(); + return rerenderDeferredValue(value, config); + }, + useTransition: function(config) { + currentHookNameInDev = "useTransition"; + updateHookTypesDev(); + return rerenderTransition(config); + } + }; InvalidNestedHooksDispatcherOnMountInDEV = { readContext: function(context, observedBits) { warnInvalidContextAccess(); @@ -11961,6 +12094,111 @@ var InvalidNestedHooksDispatcherOnUpdateInDEV = null; return updateTransition(config); } }; + InvalidNestedHooksDispatcherOnRerenderInDEV = { + readContext: function(context, observedBits) { + warnInvalidContextAccess(); + return readContext(context, observedBits); + }, + useCallback: function(callback, deps) { + currentHookNameInDev = "useCallback"; + warnInvalidHookAccess(); + updateHookTypesDev(); + return updateCallback(callback, deps); + }, + useContext: function(context, observedBits) { + currentHookNameInDev = "useContext"; + warnInvalidHookAccess(); + updateHookTypesDev(); + return readContext(context, observedBits); + }, + useEffect: function(create, deps) { + currentHookNameInDev = "useEffect"; + warnInvalidHookAccess(); + updateHookTypesDev(); + return updateEffect(create, deps); + }, + useImperativeHandle: function(ref, create, deps) { + currentHookNameInDev = "useImperativeHandle"; + warnInvalidHookAccess(); + updateHookTypesDev(); + return updateImperativeHandle(ref, create, deps); + }, + useLayoutEffect: function(create, deps) { + currentHookNameInDev = "useLayoutEffect"; + warnInvalidHookAccess(); + updateHookTypesDev(); + return updateLayoutEffect(create, deps); + }, + useMemo: function(create, deps) { + currentHookNameInDev = "useMemo"; + warnInvalidHookAccess(); + updateHookTypesDev(); + var prevDispatcher = ReactCurrentDispatcher$1.current; + ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV; + + try { + return updateMemo(create, deps); + } finally { + ReactCurrentDispatcher$1.current = prevDispatcher; + } + }, + useReducer: function(reducer, initialArg, init) { + currentHookNameInDev = "useReducer"; + warnInvalidHookAccess(); + updateHookTypesDev(); + var prevDispatcher = ReactCurrentDispatcher$1.current; + ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV; + + try { + return rerenderReducer(reducer, initialArg, init); + } finally { + ReactCurrentDispatcher$1.current = prevDispatcher; + } + }, + useRef: function(initialValue) { + currentHookNameInDev = "useRef"; + warnInvalidHookAccess(); + updateHookTypesDev(); + return updateRef(initialValue); + }, + useState: function(initialState) { + currentHookNameInDev = "useState"; + warnInvalidHookAccess(); + updateHookTypesDev(); + var prevDispatcher = ReactCurrentDispatcher$1.current; + ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV; + + try { + return rerenderState(initialState); + } finally { + ReactCurrentDispatcher$1.current = prevDispatcher; + } + }, + useDebugValue: function(value, formatterFn) { + currentHookNameInDev = "useDebugValue"; + warnInvalidHookAccess(); + updateHookTypesDev(); + return updateDebugValue(value, formatterFn); + }, + useResponder: function(responder, props) { + currentHookNameInDev = "useResponder"; + warnInvalidHookAccess(); + updateHookTypesDev(); + return createDeprecatedResponderListener(responder, props); + }, + useDeferredValue: function(value, config) { + currentHookNameInDev = "useDeferredValue"; + warnInvalidHookAccess(); + updateHookTypesDev(); + return rerenderDeferredValue(value, config); + }, + useTransition: function(config) { + currentHookNameInDev = "useTransition"; + warnInvalidHookAccess(); + updateHookTypesDev(); + return rerenderTransition(config); + } + }; } // CommonJS interop named imports. @@ -13693,7 +13931,8 @@ function mountIndeterminateComponent( workInProgress.tag = ClassComponent; // Throw out any hooks that were used. - resetHooks(); // Push context providers early to prevent context stack mismatches. + workInProgress.memoizedState = null; + workInProgress.updateQueue = null; // Push context providers early to prevent context stack mismatches. // During mounting we don't know the child context yet as the instance doesn't exist. // We will invalidate the child context in finishClassComponent() right after rendering. @@ -15721,17 +15960,16 @@ var emptyObject$2 = {}; function collectScopedNodes(node, fn, scopedNodes) { if (enableScopeAPI) { if (node.tag === HostComponent) { - var _type = node.type, + var type = node.type, memoizedProps = node.memoizedProps, stateNode = node.stateNode; - - var _instance = getPublicInstance(stateNode); + var instance = getPublicInstance(stateNode); if ( - _instance !== null && - fn(_type, memoizedProps || emptyObject$2, _instance) === true + instance !== null && + fn(type, memoizedProps || emptyObject$2, instance) === true ) { - scopedNodes.push(_instance); + scopedNodes.push(instance); } } @@ -15750,17 +15988,13 @@ function collectScopedNodes(node, fn, scopedNodes) { function collectFirstScopedNode(node, fn) { if (enableScopeAPI) { if (node.tag === HostComponent) { - var _type2 = node.type, + var type = node.type, memoizedProps = node.memoizedProps, stateNode = node.stateNode; + var instance = getPublicInstance(stateNode); - var _instance2 = getPublicInstance(stateNode); - - if ( - _instance2 !== null && - fn(_type2, memoizedProps, _instance2) === true - ) { - return _instance2; + if (instance !== null && fn(type, memoizedProps, instance) === true) { + return instance; } } @@ -15803,9 +16037,10 @@ function collectFirstScopedNodeFromChildren(startingChild, fn) { return null; } -function collectNearestScopeMethods(node, scope, childrenScopes) { - if (isValidScopeNode(node, scope)) { - childrenScopes.push(node.stateNode.methods); +function collectNearestContextValues(node, context, childContextValues) { + if (node.tag === ContextProvider && node.type._context === context) { + var contextValue = node.memoizedProps.value; + childContextValues.push(contextValue); } else { var child = node.child; @@ -15814,81 +16049,27 @@ function collectNearestScopeMethods(node, scope, childrenScopes) { } if (child !== null) { - collectNearestChildScopeMethods(child, scope, childrenScopes); + collectNearestChildContextValues(child, context, childContextValues); } } } -function collectNearestChildScopeMethods(startingChild, scope, childrenScopes) { +function collectNearestChildContextValues( + startingChild, + context, + childContextValues +) { var child = startingChild; while (child !== null) { - collectNearestScopeMethods(child, scope, childrenScopes); + collectNearestContextValues(child, context, childContextValues); child = child.sibling; } } -function isValidScopeNode(node, scope) { - return ( - node.tag === ScopeComponent && - node.type === scope && - node.stateNode !== null - ); -} - function createScopeMethods(scope, instance) { return { - getChildren: function() { - var currentFiber = instance.fiber; - var child = currentFiber.child; - var childrenScopes = []; - - if (child !== null) { - collectNearestChildScopeMethods(child, scope, childrenScopes); - } - - return childrenScopes.length === 0 ? null : childrenScopes; - }, - getChildrenFromRoot: function() { - var currentFiber = instance.fiber; - var node = currentFiber; - - while (node !== null) { - var parent = node.return; - - if (parent === null) { - break; - } - - node = parent; - - if (node.tag === ScopeComponent && node.type === scope) { - break; - } - } - - var childrenScopes = []; - collectNearestChildScopeMethods(node.child, scope, childrenScopes); - return childrenScopes.length === 0 ? null : childrenScopes; - }, - getParent: function() { - var node = instance.fiber.return; - - while (node !== null) { - if (node.tag === ScopeComponent && node.type === scope) { - return node.stateNode.methods; - } - - node = node.return; - } - - return null; - }, - getProps: function() { - var currentFiber = instance.fiber; - return currentFiber.memoizedProps; - }, - queryAllNodes: function(fn) { + DO_NOT_USE_queryAllNodes: function(fn) { var currentFiber = instance.fiber; var child = currentFiber.child; var scopedNodes = []; @@ -15899,7 +16080,7 @@ function createScopeMethods(scope, instance) { return scopedNodes.length === 0 ? null : scopedNodes; }, - queryFirstNode: function(fn) { + DO_NOT_USE_queryFirstNode: function(fn) { var currentFiber = instance.fiber; var child = currentFiber.child; @@ -15925,6 +16106,17 @@ function createScopeMethods(scope, instance) { } return false; + }, + getChildContextValues: function(context) { + var currentFiber = instance.fiber; + var child = currentFiber.child; + var childContextValues = []; + + if (child !== null) { + collectNearestChildContextValues(child, context, childContextValues); + } + + return childContextValues; } }; } @@ -20323,7 +20515,7 @@ function handleError(root, thrownValue) { try { // Reset module-level state that was set during the render phase. resetContextDependencies(); - resetHooks(); + resetHooksAfterThrow(); resetCurrentFiber(); if (workInProgress === null || workInProgress.return === null) { @@ -21489,16 +21681,16 @@ function jnd(timeElapsed) { return timeElapsed < 120 ? 120 : timeElapsed < 480 - ? 480 - : timeElapsed < 1080 - ? 1080 - : timeElapsed < 1920 - ? 1920 - : timeElapsed < 3000 - ? 3000 - : timeElapsed < 4320 - ? 4320 - : ceil(timeElapsed / 1960) * 1960; + ? 480 + : timeElapsed < 1080 + ? 1080 + : timeElapsed < 1920 + ? 1920 + : timeElapsed < 3000 + ? 3000 + : timeElapsed < 4320 + ? 4320 + : ceil(timeElapsed / 1960) * 1960; } function computeMsUntilSuspenseLoadingDelay( @@ -21665,7 +21857,7 @@ if (true && replayFailedUnitOfWorkWithInvokeGuardedCallback) { // corresponding changes there. resetContextDependencies(); - resetHooks(); // Don't reset current debug fiber, since we're about to work on the + resetHooksAfterThrow(); // Don't reset current debug fiber, since we're about to work on the // same fiber again. // Unwind the failed stack frame @@ -23414,7 +23606,7 @@ function createPortal( // TODO: this is special because it gets imported during build. -var ReactVersion = "16.12.0-19f6fe170"; +var ReactVersion = "16.12.0-241c4467e"; var NativeMethodsMixin = function(findNodeHandle, findHostInstance) { /** @@ -24263,7 +24455,12 @@ var ReactFabric = { updateContainer(element, root, null, callback); return getPublicRootInstance(root); }, + // Deprecated - this function is being renamed to stopSurface, use that instead. + // TODO (T47576999): Delete this once it's no longer called from native code. unmountComponentAtNode: function(containerTag) { + this.stopSurface(containerTag); + }, + stopSurface: function(containerTag) { var root = roots.get(containerTag); if (root) { diff --git a/Libraries/Renderer/implementations/ReactFabric-prod.fb.js b/Libraries/Renderer/implementations/ReactFabric-prod.fb.js index 3ff91b8b31..8bc691111c 100644 --- a/Libraries/Renderer/implementations/ReactFabric-prod.fb.js +++ b/Libraries/Renderer/implementations/ReactFabric-prod.fb.js @@ -348,8 +348,8 @@ function SyntheticEvent( ((targetInst = dispatchConfig[propName]) ? (this[propName] = targetInst(nativeEvent)) : "target" === propName - ? (this.target = nativeEventTarget) - : (this[propName] = nativeEvent[propName])); + ? (this.target = nativeEventTarget) + : (this[propName] = nativeEvent[propName])); this.isDefaultPrevented = (null != nativeEvent.defaultPrevented ? nativeEvent.defaultPrevented : !1 === nativeEvent.returnValue) @@ -562,10 +562,10 @@ function accumulate(current, next) { return null == current ? next : Array.isArray(current) - ? current.concat(next) - : Array.isArray(next) - ? [current].concat(next) - : [current, next]; + ? current.concat(next) + : Array.isArray(next) + ? [current].concat(next) + : [current, next]; } var responderInst = null, trackedTouchCount = 0; @@ -667,10 +667,10 @@ var eventTypes = { var shouldSetEventType = isStartish(topLevelType) ? eventTypes.startShouldSetResponder : isMoveish(topLevelType) - ? eventTypes.moveShouldSetResponder - : "topSelectionChange" === topLevelType - ? eventTypes.selectionChangeShouldSetResponder - : eventTypes.scrollShouldSetResponder; + ? eventTypes.moveShouldSetResponder + : "topSelectionChange" === topLevelType + ? eventTypes.selectionChangeShouldSetResponder + : eventTypes.scrollShouldSetResponder; if (responderInst) b: { var JSCompiler_temp = responderInst; @@ -824,10 +824,10 @@ var eventTypes = { (shouldSetEventType = shouldSetEventType ? eventTypes.responderStart : JSCompiler_temp - ? eventTypes.responderMove - : targetInst - ? eventTypes.responderEnd - : null) + ? eventTypes.responderMove + : targetInst + ? eventTypes.responderEnd + : null) ) (shouldSetEventType = ResponderSyntheticEvent.getPooled( shouldSetEventType, @@ -890,8 +890,8 @@ var eventTypes = { (topLevelType = shouldSetEventType ? eventTypes.responderTerminate : topLevelType - ? eventTypes.responderRelease - : null) + ? eventTypes.responderRelease + : null) ) (nativeEvent = ResponderSyntheticEvent.getPooled( topLevelType, @@ -1267,8 +1267,8 @@ function diffNestedProperty( return nextProp ? addNestedProperty(updatePayload, nextProp, validAttributes) : prevProp - ? clearNestedProperty(updatePayload, prevProp, validAttributes) - : updatePayload; + ? clearNestedProperty(updatePayload, prevProp, validAttributes) + : updatePayload; if (!Array.isArray(prevProp) && !Array.isArray(nextProp)) return diffProperties(updatePayload, prevProp, nextProp, validAttributes); if (Array.isArray(prevProp) && Array.isArray(nextProp)) { @@ -1853,10 +1853,10 @@ function flushSyncCallbackQueueImpl() { function is(x, y) { return (x === y && (0 !== x || 1 / x === 1 / y)) || (x !== x && y !== y); } -var is$1 = "function" === typeof Object.is ? Object.is : is, +var objectIs = "function" === typeof Object.is ? Object.is : is, hasOwnProperty = Object.prototype.hasOwnProperty; function shallowEqual(objA, objB) { - if (is$1(objA, objB)) return !0; + if (objectIs(objA, objB)) return !0; if ( "object" !== typeof objA || null === objA || @@ -1870,7 +1870,7 @@ function shallowEqual(objA, objB) { for (keysB = 0; keysB < keysA.length; keysB++) if ( !hasOwnProperty.call(objB, keysA[keysB]) || - !is$1(objA[keysA[keysB]], objB[keysA[keysB]]) + !objectIs(objA[keysA[keysB]], objB[keysA[keysB]]) ) return !1; return !0; @@ -2222,8 +2222,8 @@ function checkShouldComponentUpdate( return "function" === typeof workInProgress.shouldComponentUpdate ? workInProgress.shouldComponentUpdate(newProps, newState, nextContext) : ctor.prototype && ctor.prototype.isPureReactComponent - ? !shallowEqual(oldProps, newProps) || !shallowEqual(oldState, newState) - : !0; + ? !shallowEqual(oldProps, newProps) || !shallowEqual(oldState, newState) + : !0; } function constructClassInstance(workInProgress, ctor, props) { var isLegacyContextConsumer = !1, @@ -3118,9 +3118,7 @@ var ReactCurrentDispatcher$1 = ReactSharedInternals.ReactCurrentDispatcher, currentlyRenderingFiber$1 = null, currentHook = null, workInProgressHook = null, - didScheduleRenderPhaseUpdate = !1, - renderPhaseUpdates = null, - numberOfReRenders = 0; + didScheduleRenderPhaseUpdate = !1; function throwInvalidHookError() { throw Error( "Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons:\n1. You might have mismatching versions of React and the renderer (such as React DOM)\n2. You might be breaking the Rules of Hooks\n3. You might have more than one copy of React in the same app\nSee https://fb.me/react-invalid-hook-call for tips about how to debug and fix this problem." @@ -3129,7 +3127,7 @@ function throwInvalidHookError() { function areHookInputsEqual(nextDeps, prevDeps) { if (null === prevDeps) return !1; for (var i = 0; i < prevDeps.length && i < nextDeps.length; i++) - if (!is$1(nextDeps[i], prevDeps[i])) return !1; + if (!objectIs(nextDeps[i], prevDeps[i])) return !1; return !0; } function renderWithHooks( @@ -3150,36 +3148,32 @@ function renderWithHooks( ? HooksDispatcherOnMount : HooksDispatcherOnUpdate; current = Component(props, secondArg); - if (didScheduleRenderPhaseUpdate) { - do - (didScheduleRenderPhaseUpdate = !1), - (numberOfReRenders += 1), - (workInProgressHook = currentHook = null), - (workInProgress.updateQueue = null), - (ReactCurrentDispatcher$1.current = HooksDispatcherOnUpdate), - (current = Component(props, secondArg)); - while (didScheduleRenderPhaseUpdate); - renderPhaseUpdates = null; - numberOfReRenders = 0; + if (workInProgress.expirationTime === renderExpirationTime$1) { + nextRenderExpirationTime = 0; + do { + workInProgress.expirationTime = 0; + if (!(25 > nextRenderExpirationTime)) + throw Error( + "Too many re-renders. React limits the number of renders to prevent an infinite loop." + ); + nextRenderExpirationTime += 1; + workInProgressHook = currentHook = null; + workInProgress.updateQueue = null; + ReactCurrentDispatcher$1.current = HooksDispatcherOnRerender; + current = Component(props, secondArg); + } while (workInProgress.expirationTime === renderExpirationTime$1); } ReactCurrentDispatcher$1.current = ContextOnlyDispatcher; workInProgress = null !== currentHook && null !== currentHook.next; renderExpirationTime$1 = 0; workInProgressHook = currentHook = currentlyRenderingFiber$1 = null; + didScheduleRenderPhaseUpdate = !1; if (workInProgress) throw Error( "Rendered fewer hooks than expected. This may be caused by an accidental early return statement." ); return current; } -function resetHooks() { - ReactCurrentDispatcher$1.current = ContextOnlyDispatcher; - renderExpirationTime$1 = 0; - workInProgressHook = currentHook = currentlyRenderingFiber$1 = null; - didScheduleRenderPhaseUpdate = !1; - renderPhaseUpdates = null; - numberOfReRenders = 0; -} function mountWorkInProgressHook() { var hook = { memoizedState: null, @@ -3234,57 +3228,36 @@ function updateReducer(reducer) { "Should have a queue. This is likely a bug in React. Please file an issue." ); queue.lastRenderedReducer = reducer; - if (0 < numberOfReRenders) { - var _dispatch = queue.dispatch; - if (null !== renderPhaseUpdates) { - var firstRenderPhaseUpdate = renderPhaseUpdates.get(queue); - if (void 0 !== firstRenderPhaseUpdate) { - renderPhaseUpdates.delete(queue); - var newState = hook.memoizedState; - do - (newState = reducer(newState, firstRenderPhaseUpdate.action)), - (firstRenderPhaseUpdate = firstRenderPhaseUpdate.next); - while (null !== firstRenderPhaseUpdate); - is$1(newState, hook.memoizedState) || (didReceiveUpdate = !0); - hook.memoizedState = newState; - null === hook.baseQueue && (hook.baseState = newState); - queue.lastRenderedState = newState; - return [newState, _dispatch]; - } + var current = currentHook, + baseQueue = current.baseQueue, + pendingQueue = queue.pending; + if (null !== pendingQueue) { + if (null !== baseQueue) { + var baseFirst = baseQueue.next; + baseQueue.next = pendingQueue.next; + pendingQueue.next = baseFirst; } - return [hook.memoizedState, _dispatch]; - } - newState = currentHook; - _dispatch = newState.baseQueue; - firstRenderPhaseUpdate = queue.pending; - if (null !== firstRenderPhaseUpdate) { - if (null !== _dispatch) { - var baseFirst = _dispatch.next; - _dispatch.next = firstRenderPhaseUpdate.next; - firstRenderPhaseUpdate.next = baseFirst; - } - newState.baseQueue = _dispatch = firstRenderPhaseUpdate; + current.baseQueue = baseQueue = pendingQueue; queue.pending = null; } - if (null !== _dispatch) { - _dispatch = _dispatch.next; - newState = newState.baseState; - var newBaseQueueLast = (baseFirst = firstRenderPhaseUpdate = null), - _update = _dispatch; + if (null !== baseQueue) { + baseQueue = baseQueue.next; + current = current.baseState; + var newBaseQueueLast = (baseFirst = pendingQueue = null), + update = baseQueue; do { - var updateExpirationTime = _update.expirationTime; + var updateExpirationTime = update.expirationTime; if (updateExpirationTime < renderExpirationTime$1) { var clone = { - expirationTime: _update.expirationTime, - suspenseConfig: _update.suspenseConfig, - action: _update.action, - eagerReducer: _update.eagerReducer, - eagerState: _update.eagerState, + expirationTime: update.expirationTime, + suspenseConfig: update.suspenseConfig, + action: update.action, + eagerReducer: update.eagerReducer, + eagerState: update.eagerState, next: null }; null === newBaseQueueLast - ? ((baseFirst = newBaseQueueLast = clone), - (firstRenderPhaseUpdate = newState)) + ? ((baseFirst = newBaseQueueLast = clone), (pendingQueue = current)) : (newBaseQueueLast = newBaseQueueLast.next = clone); updateExpirationTime > currentlyRenderingFiber$1.expirationTime && ((currentlyRenderingFiber$1.expirationTime = updateExpirationTime), @@ -3293,33 +3266,56 @@ function updateReducer(reducer) { null !== newBaseQueueLast && (newBaseQueueLast = newBaseQueueLast.next = { expirationTime: 1073741823, - suspenseConfig: _update.suspenseConfig, - action: _update.action, - eagerReducer: _update.eagerReducer, - eagerState: _update.eagerState, + suspenseConfig: update.suspenseConfig, + action: update.action, + eagerReducer: update.eagerReducer, + eagerState: update.eagerState, next: null }), markRenderEventTimeAndConfig( updateExpirationTime, - _update.suspenseConfig + update.suspenseConfig ), - (newState = - _update.eagerReducer === reducer - ? _update.eagerState - : reducer(newState, _update.action)); - _update = _update.next; - } while (null !== _update && _update !== _dispatch); + (current = + update.eagerReducer === reducer + ? update.eagerState + : reducer(current, update.action)); + update = update.next; + } while (null !== update && update !== baseQueue); null === newBaseQueueLast - ? (firstRenderPhaseUpdate = newState) + ? (pendingQueue = current) : (newBaseQueueLast.next = baseFirst); - is$1(newState, hook.memoizedState) || (didReceiveUpdate = !0); - hook.memoizedState = newState; - hook.baseState = firstRenderPhaseUpdate; + objectIs(current, hook.memoizedState) || (didReceiveUpdate = !0); + hook.memoizedState = current; + hook.baseState = pendingQueue; hook.baseQueue = newBaseQueueLast; - queue.lastRenderedState = newState; + queue.lastRenderedState = current; } return [hook.memoizedState, queue.dispatch]; } +function rerenderReducer(reducer) { + var hook = updateWorkInProgressHook(), + queue = hook.queue; + if (null === queue) + throw Error( + "Should have a queue. This is likely a bug in React. Please file an issue." + ); + queue.lastRenderedReducer = reducer; + var dispatch = queue.dispatch, + lastRenderPhaseUpdate = queue.pending, + newState = hook.memoizedState; + if (null !== lastRenderPhaseUpdate) { + queue.pending = null; + var update = (lastRenderPhaseUpdate = lastRenderPhaseUpdate.next); + do (newState = reducer(newState, update.action)), (update = update.next); + while (update !== lastRenderPhaseUpdate); + objectIs(newState, hook.memoizedState) || (didReceiveUpdate = !0); + hook.memoizedState = newState; + null === hook.baseQueue && (hook.baseState = newState); + queue.lastRenderedState = newState; + } + return [newState, dispatch]; +} function mountState(initialState) { var hook = mountWorkInProgressHook(); "function" === typeof initialState && (initialState = initialState()); @@ -3340,6 +3336,9 @@ function mountState(initialState) { function updateState(initialState) { return updateReducer(basicStateReducer, initialState); } +function rerenderState(initialState) { + return rerenderReducer(basicStateReducer, initialState); +} function pushEffect(tag, create, destroy, deps) { tag = { tag: tag, create: create, destroy: destroy, deps: deps, next: null }; create = currentlyRenderingFiber$1.updateQueue; @@ -3356,6 +3355,9 @@ function pushEffect(tag, create, destroy, deps) { (create.lastEffect = tag))); return tag; } +function updateRef() { + return updateWorkInProgressHook().memoizedState; +} function mountEffectImpl(fiberEffectTag, hookEffectTag, create, deps) { var hook = mountWorkInProgressHook(); currentlyRenderingFiber$1.effectTag |= fiberEffectTag; @@ -3387,6 +3389,9 @@ function mountEffect(create, deps) { function updateEffect(create, deps) { return updateEffectImpl(516, 192, create, deps); } +function updateLayoutEffect(create, deps) { + return updateEffectImpl(4, 36, create, deps); +} function imperativeHandleEffect(create, ref) { if ("function" === typeof ref) return ( @@ -3405,6 +3410,15 @@ function imperativeHandleEffect(create, ref) { } ); } +function updateImperativeHandle(ref, create, deps) { + deps = null !== deps && void 0 !== deps ? deps.concat([ref]) : null; + return updateEffectImpl( + 4, + 36, + imperativeHandleEffect.bind(null, create, ref), + deps + ); +} function mountDebugValue() {} function mountCallback(callback, deps) { mountWorkInProgressHook().memoizedState = [ @@ -3426,6 +3440,20 @@ function updateCallback(callback, deps) { hook.memoizedState = [callback, deps]; return callback; } +function updateMemo(nextCreate, deps) { + var hook = updateWorkInProgressHook(); + deps = void 0 === deps ? null : deps; + var prevState = hook.memoizedState; + if ( + null !== prevState && + null !== deps && + areHookInputsEqual(deps, prevState[1]) + ) + return prevState[0]; + nextCreate = nextCreate(); + hook.memoizedState = [nextCreate, deps]; + return nextCreate; +} function startTransition(setPending, config, callback) { var priorityLevel = getCurrentPriorityLevel(); runWithPriority(98 > priorityLevel ? 98 : priorityLevel, function() { @@ -3442,62 +3470,42 @@ function startTransition(setPending, config, callback) { }); } function dispatchAction(fiber, queue, action) { - if (!(25 > numberOfReRenders)) - throw Error( - "Too many re-renders. React limits the number of renders to prevent an infinite loop." - ); - var alternate = fiber.alternate; + var currentTime = requestCurrentTimeForUpdate(), + suspenseConfig = ReactCurrentBatchConfig.suspense; + currentTime = computeExpirationForFiber(currentTime, fiber, suspenseConfig); + suspenseConfig = { + expirationTime: currentTime, + suspenseConfig: suspenseConfig, + action: action, + eagerReducer: null, + eagerState: null, + next: null + }; + var pending = queue.pending; + null === pending + ? (suspenseConfig.next = suspenseConfig) + : ((suspenseConfig.next = pending.next), (pending.next = suspenseConfig)); + queue.pending = suspenseConfig; + pending = fiber.alternate; if ( fiber === currentlyRenderingFiber$1 || - (null !== alternate && alternate === currentlyRenderingFiber$1) + (null !== pending && pending === currentlyRenderingFiber$1) ) - if ( - ((didScheduleRenderPhaseUpdate = !0), - (fiber = { - expirationTime: renderExpirationTime$1, - suspenseConfig: null, - action: action, - eagerReducer: null, - eagerState: null, - next: null - }), - null === renderPhaseUpdates && (renderPhaseUpdates = new Map()), - (action = renderPhaseUpdates.get(queue)), - void 0 === action) - ) - renderPhaseUpdates.set(queue, fiber); - else { - for (queue = action; null !== queue.next; ) queue = queue.next; - queue.next = fiber; - } + (didScheduleRenderPhaseUpdate = !0), + (suspenseConfig.expirationTime = renderExpirationTime$1), + (currentlyRenderingFiber$1.expirationTime = renderExpirationTime$1); else { - var currentTime = requestCurrentTimeForUpdate(), - suspenseConfig = ReactCurrentBatchConfig.suspense; - currentTime = computeExpirationForFiber(currentTime, fiber, suspenseConfig); - suspenseConfig = { - expirationTime: currentTime, - suspenseConfig: suspenseConfig, - action: action, - eagerReducer: null, - eagerState: null, - next: null - }; - var pending = queue.pending; - null === pending - ? (suspenseConfig.next = suspenseConfig) - : ((suspenseConfig.next = pending.next), (pending.next = suspenseConfig)); - queue.pending = suspenseConfig; if ( 0 === fiber.expirationTime && - (null === alternate || 0 === alternate.expirationTime) && - ((alternate = queue.lastRenderedReducer), null !== alternate) + (null === pending || 0 === pending.expirationTime) && + ((pending = queue.lastRenderedReducer), null !== pending) ) try { var currentState = queue.lastRenderedState, - eagerState = alternate(currentState, action); - suspenseConfig.eagerReducer = alternate; + eagerState = pending(currentState, action); + suspenseConfig.eagerReducer = pending; suspenseConfig.eagerState = eagerState; - if (is$1(eagerState, currentState)) return; + if (objectIs(eagerState, currentState)) return; } catch (error) { } finally { } @@ -3606,36 +3614,11 @@ var ContextOnlyDispatcher = { useCallback: updateCallback, useContext: readContext, useEffect: updateEffect, - useImperativeHandle: function(ref, create, deps) { - deps = null !== deps && void 0 !== deps ? deps.concat([ref]) : null; - return updateEffectImpl( - 4, - 36, - imperativeHandleEffect.bind(null, create, ref), - deps - ); - }, - useLayoutEffect: function(create, deps) { - return updateEffectImpl(4, 36, create, deps); - }, - useMemo: function(nextCreate, deps) { - var hook = updateWorkInProgressHook(); - deps = void 0 === deps ? null : deps; - var prevState = hook.memoizedState; - if ( - null !== prevState && - null !== deps && - areHookInputsEqual(deps, prevState[1]) - ) - return prevState[0]; - nextCreate = nextCreate(); - hook.memoizedState = [nextCreate, deps]; - return nextCreate; - }, + useImperativeHandle: updateImperativeHandle, + useLayoutEffect: updateLayoutEffect, + useMemo: updateMemo, useReducer: updateReducer, - useRef: function() { - return updateWorkInProgressHook().memoizedState; - }, + useRef: updateRef, useState: updateState, useDebugValue: mountDebugValue, useResponder: createDeprecatedResponderListener, @@ -3671,6 +3654,51 @@ var ContextOnlyDispatcher = { ]; } }, + HooksDispatcherOnRerender = { + readContext: readContext, + useCallback: updateCallback, + useContext: readContext, + useEffect: updateEffect, + useImperativeHandle: updateImperativeHandle, + useLayoutEffect: updateLayoutEffect, + useMemo: updateMemo, + useReducer: rerenderReducer, + useRef: updateRef, + useState: rerenderState, + useDebugValue: mountDebugValue, + useResponder: createDeprecatedResponderListener, + useDeferredValue: function(value, config) { + var _rerenderState = rerenderState(value), + prevValue = _rerenderState[0], + setValue = _rerenderState[1]; + updateEffect( + function() { + var previousConfig = ReactCurrentBatchConfig$1.suspense; + ReactCurrentBatchConfig$1.suspense = + void 0 === config ? null : config; + try { + setValue(value); + } finally { + ReactCurrentBatchConfig$1.suspense = previousConfig; + } + }, + [value, config] + ); + return prevValue; + }, + useTransition: function(config) { + var _rerenderState2 = rerenderState(!1), + isPending = _rerenderState2[0]; + _rerenderState2 = _rerenderState2[1]; + return [ + updateCallback(startTransition.bind(null, _rerenderState2, config), [ + _rerenderState2, + config + ]), + isPending + ]; + } + }, hydrationParentFiber = null, nextHydratableInstance = null, isHydrating = !1; @@ -4696,8 +4724,8 @@ updateHostComponent$1 = function(current, workInProgress, type, newProps) { ? cloneNodeWithNewProps(recyclableInstance, newProps) : cloneNode(recyclableInstance) : null !== newProps - ? cloneNodeWithNewChildrenAndProps(recyclableInstance, newProps) - : cloneNodeWithNewChildren(recyclableInstance), + ? cloneNodeWithNewChildrenAndProps(recyclableInstance, newProps) + : cloneNodeWithNewChildren(recyclableInstance), canonical: type.canonical }), (workInProgress.stateNode = type), @@ -5493,8 +5521,8 @@ function requestCurrentTimeForUpdate() { return (executionContext & (RenderContext | CommitContext)) !== NoContext ? 1073741821 - ((now() / 10) | 0) : 0 !== currentEventTime - ? currentEventTime - : (currentEventTime = 1073741821 - ((now() / 10) | 0)); + ? currentEventTime + : (currentEventTime = 1073741821 - ((now() / 10) | 0)); } function computeExpirationForFiber(currentTime, fiber, suspenseConfig) { fiber = fiber.mode; @@ -5601,9 +5629,10 @@ function getNextRootExpirationTimeToWorkOn(root) { if (0 !== lastExpiredTime) return lastExpiredTime; lastExpiredTime = root.firstPendingTime; if (!isRootSuspendedAtTime(root, lastExpiredTime)) return lastExpiredTime; - lastExpiredTime = root.lastPingedTime; + var lastPingedTime = root.lastPingedTime; root = root.nextKnownPendingLevel; - return lastExpiredTime > root ? lastExpiredTime : root; + root = lastPingedTime > root ? lastPingedTime : root; + return 2 >= root && lastExpiredTime !== root ? 0 : root; } function ensureRootIsScheduled(root) { if (0 !== root.lastExpiredTime) @@ -5625,18 +5654,18 @@ function ensureRootIsScheduled(root) { 1073741823 === expirationTime ? (priorityLevel = 99) : 1 === expirationTime || 2 === expirationTime - ? (priorityLevel = 95) - : ((priorityLevel = - 10 * (1073741821 - expirationTime) - - 10 * (1073741821 - priorityLevel)), - (priorityLevel = - 0 >= priorityLevel - ? 99 - : 250 >= priorityLevel - ? 98 - : 5250 >= priorityLevel - ? 97 - : 95)); + ? (priorityLevel = 95) + : ((priorityLevel = + 10 * (1073741821 - expirationTime) - + 10 * (1073741821 - priorityLevel)), + (priorityLevel = + 0 >= priorityLevel + ? 99 + : 250 >= priorityLevel + ? 98 + : 5250 >= priorityLevel + ? 97 + : 95)); if (null !== existingCallbackNode) { var existingCallbackPriority = root.callbackPriority; if ( @@ -5786,35 +5815,34 @@ function performConcurrentWorkOnRoot(root, didTimeout) { 10 * (1073741821 - workInProgressRootLatestSuspenseTimeout) - now()) : 1073741823 === workInProgressRootLatestProcessedExpirationTime - ? (prevExecutionContext = 0) - : ((prevExecutionContext = - 10 * - (1073741821 - - workInProgressRootLatestProcessedExpirationTime) - - 5e3), - (prevDispatcher = now()), - (expirationTime = - 10 * (1073741821 - expirationTime) - prevDispatcher), - (prevExecutionContext = - prevDispatcher - prevExecutionContext), - 0 > prevExecutionContext && (prevExecutionContext = 0), - (prevExecutionContext = - (120 > prevExecutionContext - ? 120 - : 480 > prevExecutionContext - ? 480 - : 1080 > prevExecutionContext - ? 1080 - : 1920 > prevExecutionContext - ? 1920 - : 3e3 > prevExecutionContext - ? 3e3 - : 4320 > prevExecutionContext - ? 4320 - : 1960 * ceil(prevExecutionContext / 1960)) - - prevExecutionContext), - expirationTime < prevExecutionContext && - (prevExecutionContext = expirationTime)); + ? (prevExecutionContext = 0) + : ((prevExecutionContext = + 10 * + (1073741821 - + workInProgressRootLatestProcessedExpirationTime) - + 5e3), + (prevDispatcher = now()), + (expirationTime = + 10 * (1073741821 - expirationTime) - prevDispatcher), + (prevExecutionContext = prevDispatcher - prevExecutionContext), + 0 > prevExecutionContext && (prevExecutionContext = 0), + (prevExecutionContext = + (120 > prevExecutionContext + ? 120 + : 480 > prevExecutionContext + ? 480 + : 1080 > prevExecutionContext + ? 1080 + : 1920 > prevExecutionContext + ? 1920 + : 3e3 > prevExecutionContext + ? 3e3 + : 4320 > prevExecutionContext + ? 4320 + : 1960 * ceil(prevExecutionContext / 1960)) - + prevExecutionContext), + expirationTime < prevExecutionContext && + (prevExecutionContext = expirationTime)); if (10 < prevExecutionContext) { root.timeoutHandle = scheduleTimeout( commitRoot.bind(null, root), @@ -5969,7 +5997,20 @@ function handleError(root$jscomp$0, thrownValue) { do { try { resetContextDependencies(); - resetHooks(); + ReactCurrentDispatcher$1.current = ContextOnlyDispatcher; + if (didScheduleRenderPhaseUpdate) + for ( + var hook = currentlyRenderingFiber$1.memoizedState; + null !== hook; + + ) { + var queue = hook.queue; + null !== queue && (queue.pending = null); + hook = hook.next; + } + renderExpirationTime$1 = 0; + workInProgressHook = currentHook = currentlyRenderingFiber$1 = null; + didScheduleRenderPhaseUpdate = !1; if (null === workInProgress || null === workInProgress.return) return ( (workInProgressRootExitStatus = RootFatalErrored), @@ -6012,10 +6053,10 @@ function handleError(root$jscomp$0, thrownValue) { void 0 === props.fallback ? !1 : !0 !== props.unstable_avoidThisFallback - ? !0 - : hasInvisibleParentBoundary - ? !1 - : !0; + ? !0 + : hasInvisibleParentBoundary + ? !1 + : !0; } } if (JSCompiler_temp) { @@ -6542,10 +6583,7 @@ function pingSuspendedRoot(root, thenable, suspendedTime) { : isRootSuspendedAtTime(root, suspendedTime) && ((thenable = root.lastPingedTime), (0 !== thenable && thenable < suspendedTime) || - ((root.lastPingedTime = suspendedTime), - root.finishedExpirationTime === suspendedTime && - ((root.finishedExpirationTime = 0), (root.finishedWork = null)), - ensureRootIsScheduled(root))); + ((root.lastPingedTime = suspendedTime), ensureRootIsScheduled(root))); } function resolveRetryThenable(boundaryFiber, thenable) { var retryCache = boundaryFiber.stateNode; @@ -6680,7 +6718,8 @@ beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { void 0 === renderState.$$typeof ) { workInProgress.tag = 1; - resetHooks(); + workInProgress.memoizedState = null; + workInProgress.updateQueue = null; if (isContextProvider(updateExpirationTime)) { var hasContext = !0; pushContextProvider(workInProgress); @@ -6953,7 +6992,7 @@ beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { pushProvider(workInProgress, hasContext); if (null !== getDerivedStateFromProps) { var oldValue = getDerivedStateFromProps.value; - hasContext = is$1(oldValue, hasContext) + hasContext = objectIs(oldValue, hasContext) ? 0 : ("function" === typeof updateExpirationTime._calculateChangedBits ? updateExpirationTime._calculateChangedBits( @@ -7508,8 +7547,8 @@ function findNodeHandle(componentOrHandle) { return null == componentOrHandle ? componentOrHandle : componentOrHandle.canonical - ? componentOrHandle.canonical._nativeTag - : componentOrHandle._nativeTag; + ? componentOrHandle.canonical._nativeTag + : componentOrHandle._nativeTag; } batchedUpdatesImpl = function(fn, a) { var prevExecutionContext = executionContext; @@ -7632,8 +7671,8 @@ var roots = new Map(), return null == componentOrHandle ? componentOrHandle : componentOrHandle.canonical - ? componentOrHandle.canonical - : componentOrHandle; + ? componentOrHandle.canonical + : componentOrHandle; }, findNodeHandle: findNodeHandle, dispatchCommand: function(handle, command, args) { @@ -7673,6 +7712,9 @@ var roots = new Map(), return element; }, unmountComponentAtNode: function(containerTag) { + this.stopSurface(containerTag); + }, + stopSurface: function(containerTag) { var root = roots.get(containerTag); root && updateContainer(null, root, null, function() { @@ -7807,7 +7849,7 @@ var roots = new Map(), throw Error("getInspectorDataForViewTag() is not available in production"); }, bundleType: 0, - version: "16.12.0-experimental-19f6fe170", + version: "16.12.0-experimental-241c4467e", rendererPackageName: "react-native-renderer" }); var ReactFabric$2 = { default: ReactFabric }, diff --git a/Libraries/Renderer/implementations/ReactFabric-prod.js b/Libraries/Renderer/implementations/ReactFabric-prod.js index 521068f874..f30bc2095a 100644 --- a/Libraries/Renderer/implementations/ReactFabric-prod.js +++ b/Libraries/Renderer/implementations/ReactFabric-prod.js @@ -349,8 +349,8 @@ function SyntheticEvent( ((targetInst = dispatchConfig[propName]) ? (this[propName] = targetInst(nativeEvent)) : "target" === propName - ? (this.target = nativeEventTarget) - : (this[propName] = nativeEvent[propName])); + ? (this.target = nativeEventTarget) + : (this[propName] = nativeEvent[propName])); this.isDefaultPrevented = (null != nativeEvent.defaultPrevented ? nativeEvent.defaultPrevented : !1 === nativeEvent.returnValue) @@ -563,10 +563,10 @@ function accumulate(current, next) { return null == current ? next : Array.isArray(current) - ? current.concat(next) - : Array.isArray(next) - ? [current].concat(next) - : [current, next]; + ? current.concat(next) + : Array.isArray(next) + ? [current].concat(next) + : [current, next]; } var responderInst = null, trackedTouchCount = 0; @@ -668,10 +668,10 @@ var eventTypes = { var shouldSetEventType = isStartish(topLevelType) ? eventTypes.startShouldSetResponder : isMoveish(topLevelType) - ? eventTypes.moveShouldSetResponder - : "topSelectionChange" === topLevelType - ? eventTypes.selectionChangeShouldSetResponder - : eventTypes.scrollShouldSetResponder; + ? eventTypes.moveShouldSetResponder + : "topSelectionChange" === topLevelType + ? eventTypes.selectionChangeShouldSetResponder + : eventTypes.scrollShouldSetResponder; if (responderInst) b: { var JSCompiler_temp = responderInst; @@ -825,10 +825,10 @@ var eventTypes = { (shouldSetEventType = shouldSetEventType ? eventTypes.responderStart : JSCompiler_temp - ? eventTypes.responderMove - : targetInst - ? eventTypes.responderEnd - : null) + ? eventTypes.responderMove + : targetInst + ? eventTypes.responderEnd + : null) ) (shouldSetEventType = ResponderSyntheticEvent.getPooled( shouldSetEventType, @@ -891,8 +891,8 @@ var eventTypes = { (topLevelType = shouldSetEventType ? eventTypes.responderTerminate : topLevelType - ? eventTypes.responderRelease - : null) + ? eventTypes.responderRelease + : null) ) (nativeEvent = ResponderSyntheticEvent.getPooled( topLevelType, @@ -1260,8 +1260,8 @@ function diffNestedProperty( return nextProp ? addNestedProperty(updatePayload, nextProp, validAttributes) : prevProp - ? clearNestedProperty(updatePayload, prevProp, validAttributes) - : updatePayload; + ? clearNestedProperty(updatePayload, prevProp, validAttributes) + : updatePayload; if (!Array.isArray(prevProp) && !Array.isArray(nextProp)) return diffProperties(updatePayload, prevProp, nextProp, validAttributes); if (Array.isArray(prevProp) && Array.isArray(nextProp)) { @@ -1844,10 +1844,10 @@ function flushSyncCallbackQueueImpl() { function is(x, y) { return (x === y && (0 !== x || 1 / x === 1 / y)) || (x !== x && y !== y); } -var is$1 = "function" === typeof Object.is ? Object.is : is, +var objectIs = "function" === typeof Object.is ? Object.is : is, hasOwnProperty = Object.prototype.hasOwnProperty; function shallowEqual(objA, objB) { - if (is$1(objA, objB)) return !0; + if (objectIs(objA, objB)) return !0; if ( "object" !== typeof objA || null === objA || @@ -1861,7 +1861,7 @@ function shallowEqual(objA, objB) { for (keysB = 0; keysB < keysA.length; keysB++) if ( !hasOwnProperty.call(objB, keysA[keysB]) || - !is$1(objA[keysA[keysB]], objB[keysA[keysB]]) + !objectIs(objA[keysA[keysB]], objB[keysA[keysB]]) ) return !1; return !0; @@ -2213,8 +2213,8 @@ function checkShouldComponentUpdate( return "function" === typeof workInProgress.shouldComponentUpdate ? workInProgress.shouldComponentUpdate(newProps, newState, nextContext) : ctor.prototype && ctor.prototype.isPureReactComponent - ? !shallowEqual(oldProps, newProps) || !shallowEqual(oldState, newState) - : !0; + ? !shallowEqual(oldProps, newProps) || !shallowEqual(oldState, newState) + : !0; } function constructClassInstance(workInProgress, ctor, props) { var isLegacyContextConsumer = !1, @@ -3109,9 +3109,7 @@ var ReactCurrentDispatcher$1 = ReactSharedInternals.ReactCurrentDispatcher, currentlyRenderingFiber$1 = null, currentHook = null, workInProgressHook = null, - didScheduleRenderPhaseUpdate = !1, - renderPhaseUpdates = null, - numberOfReRenders = 0; + didScheduleRenderPhaseUpdate = !1; function throwInvalidHookError() { throw Error( "Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons:\n1. You might have mismatching versions of React and the renderer (such as React DOM)\n2. You might be breaking the Rules of Hooks\n3. You might have more than one copy of React in the same app\nSee https://fb.me/react-invalid-hook-call for tips about how to debug and fix this problem." @@ -3120,7 +3118,7 @@ function throwInvalidHookError() { function areHookInputsEqual(nextDeps, prevDeps) { if (null === prevDeps) return !1; for (var i = 0; i < prevDeps.length && i < nextDeps.length; i++) - if (!is$1(nextDeps[i], prevDeps[i])) return !1; + if (!objectIs(nextDeps[i], prevDeps[i])) return !1; return !0; } function renderWithHooks( @@ -3141,36 +3139,32 @@ function renderWithHooks( ? HooksDispatcherOnMount : HooksDispatcherOnUpdate; current = Component(props, secondArg); - if (didScheduleRenderPhaseUpdate) { - do - (didScheduleRenderPhaseUpdate = !1), - (numberOfReRenders += 1), - (workInProgressHook = currentHook = null), - (workInProgress.updateQueue = null), - (ReactCurrentDispatcher$1.current = HooksDispatcherOnUpdate), - (current = Component(props, secondArg)); - while (didScheduleRenderPhaseUpdate); - renderPhaseUpdates = null; - numberOfReRenders = 0; + if (workInProgress.expirationTime === renderExpirationTime$1) { + nextRenderExpirationTime = 0; + do { + workInProgress.expirationTime = 0; + if (!(25 > nextRenderExpirationTime)) + throw Error( + "Too many re-renders. React limits the number of renders to prevent an infinite loop." + ); + nextRenderExpirationTime += 1; + workInProgressHook = currentHook = null; + workInProgress.updateQueue = null; + ReactCurrentDispatcher$1.current = HooksDispatcherOnRerender; + current = Component(props, secondArg); + } while (workInProgress.expirationTime === renderExpirationTime$1); } ReactCurrentDispatcher$1.current = ContextOnlyDispatcher; workInProgress = null !== currentHook && null !== currentHook.next; renderExpirationTime$1 = 0; workInProgressHook = currentHook = currentlyRenderingFiber$1 = null; + didScheduleRenderPhaseUpdate = !1; if (workInProgress) throw Error( "Rendered fewer hooks than expected. This may be caused by an accidental early return statement." ); return current; } -function resetHooks() { - ReactCurrentDispatcher$1.current = ContextOnlyDispatcher; - renderExpirationTime$1 = 0; - workInProgressHook = currentHook = currentlyRenderingFiber$1 = null; - didScheduleRenderPhaseUpdate = !1; - renderPhaseUpdates = null; - numberOfReRenders = 0; -} function mountWorkInProgressHook() { var hook = { memoizedState: null, @@ -3225,57 +3219,36 @@ function updateReducer(reducer) { "Should have a queue. This is likely a bug in React. Please file an issue." ); queue.lastRenderedReducer = reducer; - if (0 < numberOfReRenders) { - var _dispatch = queue.dispatch; - if (null !== renderPhaseUpdates) { - var firstRenderPhaseUpdate = renderPhaseUpdates.get(queue); - if (void 0 !== firstRenderPhaseUpdate) { - renderPhaseUpdates.delete(queue); - var newState = hook.memoizedState; - do - (newState = reducer(newState, firstRenderPhaseUpdate.action)), - (firstRenderPhaseUpdate = firstRenderPhaseUpdate.next); - while (null !== firstRenderPhaseUpdate); - is$1(newState, hook.memoizedState) || (didReceiveUpdate = !0); - hook.memoizedState = newState; - null === hook.baseQueue && (hook.baseState = newState); - queue.lastRenderedState = newState; - return [newState, _dispatch]; - } + var current = currentHook, + baseQueue = current.baseQueue, + pendingQueue = queue.pending; + if (null !== pendingQueue) { + if (null !== baseQueue) { + var baseFirst = baseQueue.next; + baseQueue.next = pendingQueue.next; + pendingQueue.next = baseFirst; } - return [hook.memoizedState, _dispatch]; - } - newState = currentHook; - _dispatch = newState.baseQueue; - firstRenderPhaseUpdate = queue.pending; - if (null !== firstRenderPhaseUpdate) { - if (null !== _dispatch) { - var baseFirst = _dispatch.next; - _dispatch.next = firstRenderPhaseUpdate.next; - firstRenderPhaseUpdate.next = baseFirst; - } - newState.baseQueue = _dispatch = firstRenderPhaseUpdate; + current.baseQueue = baseQueue = pendingQueue; queue.pending = null; } - if (null !== _dispatch) { - _dispatch = _dispatch.next; - newState = newState.baseState; - var newBaseQueueLast = (baseFirst = firstRenderPhaseUpdate = null), - _update = _dispatch; + if (null !== baseQueue) { + baseQueue = baseQueue.next; + current = current.baseState; + var newBaseQueueLast = (baseFirst = pendingQueue = null), + update = baseQueue; do { - var updateExpirationTime = _update.expirationTime; + var updateExpirationTime = update.expirationTime; if (updateExpirationTime < renderExpirationTime$1) { var clone = { - expirationTime: _update.expirationTime, - suspenseConfig: _update.suspenseConfig, - action: _update.action, - eagerReducer: _update.eagerReducer, - eagerState: _update.eagerState, + expirationTime: update.expirationTime, + suspenseConfig: update.suspenseConfig, + action: update.action, + eagerReducer: update.eagerReducer, + eagerState: update.eagerState, next: null }; null === newBaseQueueLast - ? ((baseFirst = newBaseQueueLast = clone), - (firstRenderPhaseUpdate = newState)) + ? ((baseFirst = newBaseQueueLast = clone), (pendingQueue = current)) : (newBaseQueueLast = newBaseQueueLast.next = clone); updateExpirationTime > currentlyRenderingFiber$1.expirationTime && ((currentlyRenderingFiber$1.expirationTime = updateExpirationTime), @@ -3284,33 +3257,56 @@ function updateReducer(reducer) { null !== newBaseQueueLast && (newBaseQueueLast = newBaseQueueLast.next = { expirationTime: 1073741823, - suspenseConfig: _update.suspenseConfig, - action: _update.action, - eagerReducer: _update.eagerReducer, - eagerState: _update.eagerState, + suspenseConfig: update.suspenseConfig, + action: update.action, + eagerReducer: update.eagerReducer, + eagerState: update.eagerState, next: null }), markRenderEventTimeAndConfig( updateExpirationTime, - _update.suspenseConfig + update.suspenseConfig ), - (newState = - _update.eagerReducer === reducer - ? _update.eagerState - : reducer(newState, _update.action)); - _update = _update.next; - } while (null !== _update && _update !== _dispatch); + (current = + update.eagerReducer === reducer + ? update.eagerState + : reducer(current, update.action)); + update = update.next; + } while (null !== update && update !== baseQueue); null === newBaseQueueLast - ? (firstRenderPhaseUpdate = newState) + ? (pendingQueue = current) : (newBaseQueueLast.next = baseFirst); - is$1(newState, hook.memoizedState) || (didReceiveUpdate = !0); - hook.memoizedState = newState; - hook.baseState = firstRenderPhaseUpdate; + objectIs(current, hook.memoizedState) || (didReceiveUpdate = !0); + hook.memoizedState = current; + hook.baseState = pendingQueue; hook.baseQueue = newBaseQueueLast; - queue.lastRenderedState = newState; + queue.lastRenderedState = current; } return [hook.memoizedState, queue.dispatch]; } +function rerenderReducer(reducer) { + var hook = updateWorkInProgressHook(), + queue = hook.queue; + if (null === queue) + throw Error( + "Should have a queue. This is likely a bug in React. Please file an issue." + ); + queue.lastRenderedReducer = reducer; + var dispatch = queue.dispatch, + lastRenderPhaseUpdate = queue.pending, + newState = hook.memoizedState; + if (null !== lastRenderPhaseUpdate) { + queue.pending = null; + var update = (lastRenderPhaseUpdate = lastRenderPhaseUpdate.next); + do (newState = reducer(newState, update.action)), (update = update.next); + while (update !== lastRenderPhaseUpdate); + objectIs(newState, hook.memoizedState) || (didReceiveUpdate = !0); + hook.memoizedState = newState; + null === hook.baseQueue && (hook.baseState = newState); + queue.lastRenderedState = newState; + } + return [newState, dispatch]; +} function mountState(initialState) { var hook = mountWorkInProgressHook(); "function" === typeof initialState && (initialState = initialState()); @@ -3331,6 +3327,9 @@ function mountState(initialState) { function updateState(initialState) { return updateReducer(basicStateReducer, initialState); } +function rerenderState(initialState) { + return rerenderReducer(basicStateReducer, initialState); +} function pushEffect(tag, create, destroy, deps) { tag = { tag: tag, create: create, destroy: destroy, deps: deps, next: null }; create = currentlyRenderingFiber$1.updateQueue; @@ -3347,6 +3346,9 @@ function pushEffect(tag, create, destroy, deps) { (create.lastEffect = tag))); return tag; } +function updateRef() { + return updateWorkInProgressHook().memoizedState; +} function mountEffectImpl(fiberEffectTag, hookEffectTag, create, deps) { var hook = mountWorkInProgressHook(); currentlyRenderingFiber$1.effectTag |= fiberEffectTag; @@ -3378,6 +3380,9 @@ function mountEffect(create, deps) { function updateEffect(create, deps) { return updateEffectImpl(516, 192, create, deps); } +function updateLayoutEffect(create, deps) { + return updateEffectImpl(4, 36, create, deps); +} function imperativeHandleEffect(create, ref) { if ("function" === typeof ref) return ( @@ -3396,6 +3401,15 @@ function imperativeHandleEffect(create, ref) { } ); } +function updateImperativeHandle(ref, create, deps) { + deps = null !== deps && void 0 !== deps ? deps.concat([ref]) : null; + return updateEffectImpl( + 4, + 36, + imperativeHandleEffect.bind(null, create, ref), + deps + ); +} function mountDebugValue() {} function mountCallback(callback, deps) { mountWorkInProgressHook().memoizedState = [ @@ -3417,6 +3431,20 @@ function updateCallback(callback, deps) { hook.memoizedState = [callback, deps]; return callback; } +function updateMemo(nextCreate, deps) { + var hook = updateWorkInProgressHook(); + deps = void 0 === deps ? null : deps; + var prevState = hook.memoizedState; + if ( + null !== prevState && + null !== deps && + areHookInputsEqual(deps, prevState[1]) + ) + return prevState[0]; + nextCreate = nextCreate(); + hook.memoizedState = [nextCreate, deps]; + return nextCreate; +} function startTransition(setPending, config, callback) { var priorityLevel = getCurrentPriorityLevel(); runWithPriority(98 > priorityLevel ? 98 : priorityLevel, function() { @@ -3433,62 +3461,42 @@ function startTransition(setPending, config, callback) { }); } function dispatchAction(fiber, queue, action) { - if (!(25 > numberOfReRenders)) - throw Error( - "Too many re-renders. React limits the number of renders to prevent an infinite loop." - ); - var alternate = fiber.alternate; + var currentTime = requestCurrentTimeForUpdate(), + suspenseConfig = ReactCurrentBatchConfig.suspense; + currentTime = computeExpirationForFiber(currentTime, fiber, suspenseConfig); + suspenseConfig = { + expirationTime: currentTime, + suspenseConfig: suspenseConfig, + action: action, + eagerReducer: null, + eagerState: null, + next: null + }; + var pending = queue.pending; + null === pending + ? (suspenseConfig.next = suspenseConfig) + : ((suspenseConfig.next = pending.next), (pending.next = suspenseConfig)); + queue.pending = suspenseConfig; + pending = fiber.alternate; if ( fiber === currentlyRenderingFiber$1 || - (null !== alternate && alternate === currentlyRenderingFiber$1) + (null !== pending && pending === currentlyRenderingFiber$1) ) - if ( - ((didScheduleRenderPhaseUpdate = !0), - (fiber = { - expirationTime: renderExpirationTime$1, - suspenseConfig: null, - action: action, - eagerReducer: null, - eagerState: null, - next: null - }), - null === renderPhaseUpdates && (renderPhaseUpdates = new Map()), - (action = renderPhaseUpdates.get(queue)), - void 0 === action) - ) - renderPhaseUpdates.set(queue, fiber); - else { - for (queue = action; null !== queue.next; ) queue = queue.next; - queue.next = fiber; - } + (didScheduleRenderPhaseUpdate = !0), + (suspenseConfig.expirationTime = renderExpirationTime$1), + (currentlyRenderingFiber$1.expirationTime = renderExpirationTime$1); else { - var currentTime = requestCurrentTimeForUpdate(), - suspenseConfig = ReactCurrentBatchConfig.suspense; - currentTime = computeExpirationForFiber(currentTime, fiber, suspenseConfig); - suspenseConfig = { - expirationTime: currentTime, - suspenseConfig: suspenseConfig, - action: action, - eagerReducer: null, - eagerState: null, - next: null - }; - var pending = queue.pending; - null === pending - ? (suspenseConfig.next = suspenseConfig) - : ((suspenseConfig.next = pending.next), (pending.next = suspenseConfig)); - queue.pending = suspenseConfig; if ( 0 === fiber.expirationTime && - (null === alternate || 0 === alternate.expirationTime) && - ((alternate = queue.lastRenderedReducer), null !== alternate) + (null === pending || 0 === pending.expirationTime) && + ((pending = queue.lastRenderedReducer), null !== pending) ) try { var currentState = queue.lastRenderedState, - eagerState = alternate(currentState, action); - suspenseConfig.eagerReducer = alternate; + eagerState = pending(currentState, action); + suspenseConfig.eagerReducer = pending; suspenseConfig.eagerState = eagerState; - if (is$1(eagerState, currentState)) return; + if (objectIs(eagerState, currentState)) return; } catch (error) { } finally { } @@ -3597,36 +3605,11 @@ var ContextOnlyDispatcher = { useCallback: updateCallback, useContext: readContext, useEffect: updateEffect, - useImperativeHandle: function(ref, create, deps) { - deps = null !== deps && void 0 !== deps ? deps.concat([ref]) : null; - return updateEffectImpl( - 4, - 36, - imperativeHandleEffect.bind(null, create, ref), - deps - ); - }, - useLayoutEffect: function(create, deps) { - return updateEffectImpl(4, 36, create, deps); - }, - useMemo: function(nextCreate, deps) { - var hook = updateWorkInProgressHook(); - deps = void 0 === deps ? null : deps; - var prevState = hook.memoizedState; - if ( - null !== prevState && - null !== deps && - areHookInputsEqual(deps, prevState[1]) - ) - return prevState[0]; - nextCreate = nextCreate(); - hook.memoizedState = [nextCreate, deps]; - return nextCreate; - }, + useImperativeHandle: updateImperativeHandle, + useLayoutEffect: updateLayoutEffect, + useMemo: updateMemo, useReducer: updateReducer, - useRef: function() { - return updateWorkInProgressHook().memoizedState; - }, + useRef: updateRef, useState: updateState, useDebugValue: mountDebugValue, useResponder: createDeprecatedResponderListener, @@ -3662,6 +3645,51 @@ var ContextOnlyDispatcher = { ]; } }, + HooksDispatcherOnRerender = { + readContext: readContext, + useCallback: updateCallback, + useContext: readContext, + useEffect: updateEffect, + useImperativeHandle: updateImperativeHandle, + useLayoutEffect: updateLayoutEffect, + useMemo: updateMemo, + useReducer: rerenderReducer, + useRef: updateRef, + useState: rerenderState, + useDebugValue: mountDebugValue, + useResponder: createDeprecatedResponderListener, + useDeferredValue: function(value, config) { + var _rerenderState = rerenderState(value), + prevValue = _rerenderState[0], + setValue = _rerenderState[1]; + updateEffect( + function() { + var previousConfig = ReactCurrentBatchConfig$1.suspense; + ReactCurrentBatchConfig$1.suspense = + void 0 === config ? null : config; + try { + setValue(value); + } finally { + ReactCurrentBatchConfig$1.suspense = previousConfig; + } + }, + [value, config] + ); + return prevValue; + }, + useTransition: function(config) { + var _rerenderState2 = rerenderState(!1), + isPending = _rerenderState2[0]; + _rerenderState2 = _rerenderState2[1]; + return [ + updateCallback(startTransition.bind(null, _rerenderState2, config), [ + _rerenderState2, + config + ]), + isPending + ]; + } + }, hydrationParentFiber = null, nextHydratableInstance = null, isHydrating = !1; @@ -4687,8 +4715,8 @@ updateHostComponent$1 = function(current, workInProgress, type, newProps) { ? cloneNodeWithNewProps(recyclableInstance, newProps) : cloneNode(recyclableInstance) : null !== newProps - ? cloneNodeWithNewChildrenAndProps(recyclableInstance, newProps) - : cloneNodeWithNewChildren(recyclableInstance), + ? cloneNodeWithNewChildrenAndProps(recyclableInstance, newProps) + : cloneNodeWithNewChildren(recyclableInstance), canonical: type.canonical }), (workInProgress.stateNode = type), @@ -5484,8 +5512,8 @@ function requestCurrentTimeForUpdate() { return (executionContext & (RenderContext | CommitContext)) !== NoContext ? 1073741821 - ((now() / 10) | 0) : 0 !== currentEventTime - ? currentEventTime - : (currentEventTime = 1073741821 - ((now() / 10) | 0)); + ? currentEventTime + : (currentEventTime = 1073741821 - ((now() / 10) | 0)); } function computeExpirationForFiber(currentTime, fiber, suspenseConfig) { fiber = fiber.mode; @@ -5592,9 +5620,10 @@ function getNextRootExpirationTimeToWorkOn(root) { if (0 !== lastExpiredTime) return lastExpiredTime; lastExpiredTime = root.firstPendingTime; if (!isRootSuspendedAtTime(root, lastExpiredTime)) return lastExpiredTime; - lastExpiredTime = root.lastPingedTime; + var lastPingedTime = root.lastPingedTime; root = root.nextKnownPendingLevel; - return lastExpiredTime > root ? lastExpiredTime : root; + root = lastPingedTime > root ? lastPingedTime : root; + return 2 >= root && lastExpiredTime !== root ? 0 : root; } function ensureRootIsScheduled(root) { if (0 !== root.lastExpiredTime) @@ -5616,18 +5645,18 @@ function ensureRootIsScheduled(root) { 1073741823 === expirationTime ? (priorityLevel = 99) : 1 === expirationTime || 2 === expirationTime - ? (priorityLevel = 95) - : ((priorityLevel = - 10 * (1073741821 - expirationTime) - - 10 * (1073741821 - priorityLevel)), - (priorityLevel = - 0 >= priorityLevel - ? 99 - : 250 >= priorityLevel - ? 98 - : 5250 >= priorityLevel - ? 97 - : 95)); + ? (priorityLevel = 95) + : ((priorityLevel = + 10 * (1073741821 - expirationTime) - + 10 * (1073741821 - priorityLevel)), + (priorityLevel = + 0 >= priorityLevel + ? 99 + : 250 >= priorityLevel + ? 98 + : 5250 >= priorityLevel + ? 97 + : 95)); if (null !== existingCallbackNode) { var existingCallbackPriority = root.callbackPriority; if ( @@ -5777,35 +5806,34 @@ function performConcurrentWorkOnRoot(root, didTimeout) { 10 * (1073741821 - workInProgressRootLatestSuspenseTimeout) - now()) : 1073741823 === workInProgressRootLatestProcessedExpirationTime - ? (prevExecutionContext = 0) - : ((prevExecutionContext = - 10 * - (1073741821 - - workInProgressRootLatestProcessedExpirationTime) - - 5e3), - (prevDispatcher = now()), - (expirationTime = - 10 * (1073741821 - expirationTime) - prevDispatcher), - (prevExecutionContext = - prevDispatcher - prevExecutionContext), - 0 > prevExecutionContext && (prevExecutionContext = 0), - (prevExecutionContext = - (120 > prevExecutionContext - ? 120 - : 480 > prevExecutionContext - ? 480 - : 1080 > prevExecutionContext - ? 1080 - : 1920 > prevExecutionContext - ? 1920 - : 3e3 > prevExecutionContext - ? 3e3 - : 4320 > prevExecutionContext - ? 4320 - : 1960 * ceil(prevExecutionContext / 1960)) - - prevExecutionContext), - expirationTime < prevExecutionContext && - (prevExecutionContext = expirationTime)); + ? (prevExecutionContext = 0) + : ((prevExecutionContext = + 10 * + (1073741821 - + workInProgressRootLatestProcessedExpirationTime) - + 5e3), + (prevDispatcher = now()), + (expirationTime = + 10 * (1073741821 - expirationTime) - prevDispatcher), + (prevExecutionContext = prevDispatcher - prevExecutionContext), + 0 > prevExecutionContext && (prevExecutionContext = 0), + (prevExecutionContext = + (120 > prevExecutionContext + ? 120 + : 480 > prevExecutionContext + ? 480 + : 1080 > prevExecutionContext + ? 1080 + : 1920 > prevExecutionContext + ? 1920 + : 3e3 > prevExecutionContext + ? 3e3 + : 4320 > prevExecutionContext + ? 4320 + : 1960 * ceil(prevExecutionContext / 1960)) - + prevExecutionContext), + expirationTime < prevExecutionContext && + (prevExecutionContext = expirationTime)); if (10 < prevExecutionContext) { root.timeoutHandle = scheduleTimeout( commitRoot.bind(null, root), @@ -5960,7 +5988,20 @@ function handleError(root$jscomp$0, thrownValue) { do { try { resetContextDependencies(); - resetHooks(); + ReactCurrentDispatcher$1.current = ContextOnlyDispatcher; + if (didScheduleRenderPhaseUpdate) + for ( + var hook = currentlyRenderingFiber$1.memoizedState; + null !== hook; + + ) { + var queue = hook.queue; + null !== queue && (queue.pending = null); + hook = hook.next; + } + renderExpirationTime$1 = 0; + workInProgressHook = currentHook = currentlyRenderingFiber$1 = null; + didScheduleRenderPhaseUpdate = !1; if (null === workInProgress || null === workInProgress.return) return ( (workInProgressRootExitStatus = RootFatalErrored), @@ -6003,10 +6044,10 @@ function handleError(root$jscomp$0, thrownValue) { void 0 === props.fallback ? !1 : !0 !== props.unstable_avoidThisFallback - ? !0 - : hasInvisibleParentBoundary - ? !1 - : !0; + ? !0 + : hasInvisibleParentBoundary + ? !1 + : !0; } } if (JSCompiler_temp) { @@ -6533,10 +6574,7 @@ function pingSuspendedRoot(root, thenable, suspendedTime) { : isRootSuspendedAtTime(root, suspendedTime) && ((thenable = root.lastPingedTime), (0 !== thenable && thenable < suspendedTime) || - ((root.lastPingedTime = suspendedTime), - root.finishedExpirationTime === suspendedTime && - ((root.finishedExpirationTime = 0), (root.finishedWork = null)), - ensureRootIsScheduled(root))); + ((root.lastPingedTime = suspendedTime), ensureRootIsScheduled(root))); } function resolveRetryThenable(boundaryFiber, thenable) { var retryCache = boundaryFiber.stateNode; @@ -6671,7 +6709,8 @@ beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { void 0 === renderState.$$typeof ) { workInProgress.tag = 1; - resetHooks(); + workInProgress.memoizedState = null; + workInProgress.updateQueue = null; if (isContextProvider(updateExpirationTime)) { var hasContext = !0; pushContextProvider(workInProgress); @@ -6944,7 +6983,7 @@ beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { pushProvider(workInProgress, hasContext); if (null !== getDerivedStateFromProps) { var oldValue = getDerivedStateFromProps.value; - hasContext = is$1(oldValue, hasContext) + hasContext = objectIs(oldValue, hasContext) ? 0 : ("function" === typeof updateExpirationTime._calculateChangedBits ? updateExpirationTime._calculateChangedBits( @@ -7499,8 +7538,8 @@ function findNodeHandle(componentOrHandle) { return null == componentOrHandle ? componentOrHandle : componentOrHandle.canonical - ? componentOrHandle.canonical._nativeTag - : componentOrHandle._nativeTag; + ? componentOrHandle.canonical._nativeTag + : componentOrHandle._nativeTag; } batchedUpdatesImpl = function(fn, a) { var prevExecutionContext = executionContext; @@ -7623,8 +7662,8 @@ var roots = new Map(), return null == componentOrHandle ? componentOrHandle : componentOrHandle.canonical - ? componentOrHandle.canonical - : componentOrHandle; + ? componentOrHandle.canonical + : componentOrHandle; }, findNodeHandle: findNodeHandle, dispatchCommand: function(handle, command, args) { @@ -7664,6 +7703,9 @@ var roots = new Map(), return element; }, unmountComponentAtNode: function(containerTag) { + this.stopSurface(containerTag); + }, + stopSurface: function(containerTag) { var root = roots.get(containerTag); root && updateContainer(null, root, null, function() { @@ -7798,7 +7840,7 @@ var roots = new Map(), throw Error("getInspectorDataForViewTag() is not available in production"); }, bundleType: 0, - version: "16.12.0-19f6fe170", + version: "16.12.0-241c4467e", rendererPackageName: "react-native-renderer" }); var ReactFabric$2 = { default: ReactFabric }, diff --git a/Libraries/Renderer/implementations/ReactFabric-profiling.fb.js b/Libraries/Renderer/implementations/ReactFabric-profiling.fb.js index d65855f6d9..862d848555 100644 --- a/Libraries/Renderer/implementations/ReactFabric-profiling.fb.js +++ b/Libraries/Renderer/implementations/ReactFabric-profiling.fb.js @@ -349,8 +349,8 @@ function SyntheticEvent( ((targetInst = dispatchConfig[propName]) ? (this[propName] = targetInst(nativeEvent)) : "target" === propName - ? (this.target = nativeEventTarget) - : (this[propName] = nativeEvent[propName])); + ? (this.target = nativeEventTarget) + : (this[propName] = nativeEvent[propName])); this.isDefaultPrevented = (null != nativeEvent.defaultPrevented ? nativeEvent.defaultPrevented : !1 === nativeEvent.returnValue) @@ -563,10 +563,10 @@ function accumulate(current, next) { return null == current ? next : Array.isArray(current) - ? current.concat(next) - : Array.isArray(next) - ? [current].concat(next) - : [current, next]; + ? current.concat(next) + : Array.isArray(next) + ? [current].concat(next) + : [current, next]; } var responderInst = null, trackedTouchCount = 0; @@ -668,10 +668,10 @@ var eventTypes = { var shouldSetEventType = isStartish(topLevelType) ? eventTypes.startShouldSetResponder : isMoveish(topLevelType) - ? eventTypes.moveShouldSetResponder - : "topSelectionChange" === topLevelType - ? eventTypes.selectionChangeShouldSetResponder - : eventTypes.scrollShouldSetResponder; + ? eventTypes.moveShouldSetResponder + : "topSelectionChange" === topLevelType + ? eventTypes.selectionChangeShouldSetResponder + : eventTypes.scrollShouldSetResponder; if (responderInst) b: { var JSCompiler_temp = responderInst; @@ -825,10 +825,10 @@ var eventTypes = { (shouldSetEventType = shouldSetEventType ? eventTypes.responderStart : JSCompiler_temp - ? eventTypes.responderMove - : targetInst - ? eventTypes.responderEnd - : null) + ? eventTypes.responderMove + : targetInst + ? eventTypes.responderEnd + : null) ) (shouldSetEventType = ResponderSyntheticEvent.getPooled( shouldSetEventType, @@ -891,8 +891,8 @@ var eventTypes = { (topLevelType = shouldSetEventType ? eventTypes.responderTerminate : topLevelType - ? eventTypes.responderRelease - : null) + ? eventTypes.responderRelease + : null) ) (nativeEvent = ResponderSyntheticEvent.getPooled( topLevelType, @@ -1268,8 +1268,8 @@ function diffNestedProperty( return nextProp ? addNestedProperty(updatePayload, nextProp, validAttributes) : prevProp - ? clearNestedProperty(updatePayload, prevProp, validAttributes) - : updatePayload; + ? clearNestedProperty(updatePayload, prevProp, validAttributes) + : updatePayload; if (!Array.isArray(prevProp) && !Array.isArray(nextProp)) return diffProperties(updatePayload, prevProp, nextProp, validAttributes); if (Array.isArray(prevProp) && Array.isArray(nextProp)) { @@ -1866,18 +1866,18 @@ function inferPriorityFromExpirationTime(currentTime, expirationTime) { return 0 >= currentTime ? 99 : 250 >= currentTime - ? 98 - : 5250 >= currentTime - ? 97 - : 95; + ? 98 + : 5250 >= currentTime + ? 97 + : 95; } function is(x, y) { return (x === y && (0 !== x || 1 / x === 1 / y)) || (x !== x && y !== y); } -var is$1 = "function" === typeof Object.is ? Object.is : is, +var objectIs = "function" === typeof Object.is ? Object.is : is, hasOwnProperty = Object.prototype.hasOwnProperty; function shallowEqual(objA, objB) { - if (is$1(objA, objB)) return !0; + if (objectIs(objA, objB)) return !0; if ( "object" !== typeof objA || null === objA || @@ -1891,7 +1891,7 @@ function shallowEqual(objA, objB) { for (keysB = 0; keysB < keysA.length; keysB++) if ( !hasOwnProperty.call(objB, keysA[keysB]) || - !is$1(objA[keysA[keysB]], objB[keysA[keysB]]) + !objectIs(objA[keysA[keysB]], objB[keysA[keysB]]) ) return !1; return !0; @@ -2243,8 +2243,8 @@ function checkShouldComponentUpdate( return "function" === typeof workInProgress.shouldComponentUpdate ? workInProgress.shouldComponentUpdate(newProps, newState, nextContext) : ctor.prototype && ctor.prototype.isPureReactComponent - ? !shallowEqual(oldProps, newProps) || !shallowEqual(oldState, newState) - : !0; + ? !shallowEqual(oldProps, newProps) || !shallowEqual(oldState, newState) + : !0; } function constructClassInstance(workInProgress, ctor, props) { var isLegacyContextConsumer = !1, @@ -3139,9 +3139,7 @@ var ReactCurrentDispatcher$1 = ReactSharedInternals.ReactCurrentDispatcher, currentlyRenderingFiber$1 = null, currentHook = null, workInProgressHook = null, - didScheduleRenderPhaseUpdate = !1, - renderPhaseUpdates = null, - numberOfReRenders = 0; + didScheduleRenderPhaseUpdate = !1; function throwInvalidHookError() { throw Error( "Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons:\n1. You might have mismatching versions of React and the renderer (such as React DOM)\n2. You might be breaking the Rules of Hooks\n3. You might have more than one copy of React in the same app\nSee https://fb.me/react-invalid-hook-call for tips about how to debug and fix this problem." @@ -3150,7 +3148,7 @@ function throwInvalidHookError() { function areHookInputsEqual(nextDeps, prevDeps) { if (null === prevDeps) return !1; for (var i = 0; i < prevDeps.length && i < nextDeps.length; i++) - if (!is$1(nextDeps[i], prevDeps[i])) return !1; + if (!objectIs(nextDeps[i], prevDeps[i])) return !1; return !0; } function renderWithHooks( @@ -3171,36 +3169,32 @@ function renderWithHooks( ? HooksDispatcherOnMount : HooksDispatcherOnUpdate; current = Component(props, secondArg); - if (didScheduleRenderPhaseUpdate) { - do - (didScheduleRenderPhaseUpdate = !1), - (numberOfReRenders += 1), - (workInProgressHook = currentHook = null), - (workInProgress.updateQueue = null), - (ReactCurrentDispatcher$1.current = HooksDispatcherOnUpdate), - (current = Component(props, secondArg)); - while (didScheduleRenderPhaseUpdate); - renderPhaseUpdates = null; - numberOfReRenders = 0; + if (workInProgress.expirationTime === renderExpirationTime$1) { + nextRenderExpirationTime = 0; + do { + workInProgress.expirationTime = 0; + if (!(25 > nextRenderExpirationTime)) + throw Error( + "Too many re-renders. React limits the number of renders to prevent an infinite loop." + ); + nextRenderExpirationTime += 1; + workInProgressHook = currentHook = null; + workInProgress.updateQueue = null; + ReactCurrentDispatcher$1.current = HooksDispatcherOnRerender; + current = Component(props, secondArg); + } while (workInProgress.expirationTime === renderExpirationTime$1); } ReactCurrentDispatcher$1.current = ContextOnlyDispatcher; workInProgress = null !== currentHook && null !== currentHook.next; renderExpirationTime$1 = 0; workInProgressHook = currentHook = currentlyRenderingFiber$1 = null; + didScheduleRenderPhaseUpdate = !1; if (workInProgress) throw Error( "Rendered fewer hooks than expected. This may be caused by an accidental early return statement." ); return current; } -function resetHooks() { - ReactCurrentDispatcher$1.current = ContextOnlyDispatcher; - renderExpirationTime$1 = 0; - workInProgressHook = currentHook = currentlyRenderingFiber$1 = null; - didScheduleRenderPhaseUpdate = !1; - renderPhaseUpdates = null; - numberOfReRenders = 0; -} function mountWorkInProgressHook() { var hook = { memoizedState: null, @@ -3255,57 +3249,36 @@ function updateReducer(reducer) { "Should have a queue. This is likely a bug in React. Please file an issue." ); queue.lastRenderedReducer = reducer; - if (0 < numberOfReRenders) { - var _dispatch = queue.dispatch; - if (null !== renderPhaseUpdates) { - var firstRenderPhaseUpdate = renderPhaseUpdates.get(queue); - if (void 0 !== firstRenderPhaseUpdate) { - renderPhaseUpdates.delete(queue); - var newState = hook.memoizedState; - do - (newState = reducer(newState, firstRenderPhaseUpdate.action)), - (firstRenderPhaseUpdate = firstRenderPhaseUpdate.next); - while (null !== firstRenderPhaseUpdate); - is$1(newState, hook.memoizedState) || (didReceiveUpdate = !0); - hook.memoizedState = newState; - null === hook.baseQueue && (hook.baseState = newState); - queue.lastRenderedState = newState; - return [newState, _dispatch]; - } + var current = currentHook, + baseQueue = current.baseQueue, + pendingQueue = queue.pending; + if (null !== pendingQueue) { + if (null !== baseQueue) { + var baseFirst = baseQueue.next; + baseQueue.next = pendingQueue.next; + pendingQueue.next = baseFirst; } - return [hook.memoizedState, _dispatch]; - } - newState = currentHook; - _dispatch = newState.baseQueue; - firstRenderPhaseUpdate = queue.pending; - if (null !== firstRenderPhaseUpdate) { - if (null !== _dispatch) { - var baseFirst = _dispatch.next; - _dispatch.next = firstRenderPhaseUpdate.next; - firstRenderPhaseUpdate.next = baseFirst; - } - newState.baseQueue = _dispatch = firstRenderPhaseUpdate; + current.baseQueue = baseQueue = pendingQueue; queue.pending = null; } - if (null !== _dispatch) { - _dispatch = _dispatch.next; - newState = newState.baseState; - var newBaseQueueLast = (baseFirst = firstRenderPhaseUpdate = null), - _update = _dispatch; + if (null !== baseQueue) { + baseQueue = baseQueue.next; + current = current.baseState; + var newBaseQueueLast = (baseFirst = pendingQueue = null), + update = baseQueue; do { - var updateExpirationTime = _update.expirationTime; + var updateExpirationTime = update.expirationTime; if (updateExpirationTime < renderExpirationTime$1) { var clone = { - expirationTime: _update.expirationTime, - suspenseConfig: _update.suspenseConfig, - action: _update.action, - eagerReducer: _update.eagerReducer, - eagerState: _update.eagerState, + expirationTime: update.expirationTime, + suspenseConfig: update.suspenseConfig, + action: update.action, + eagerReducer: update.eagerReducer, + eagerState: update.eagerState, next: null }; null === newBaseQueueLast - ? ((baseFirst = newBaseQueueLast = clone), - (firstRenderPhaseUpdate = newState)) + ? ((baseFirst = newBaseQueueLast = clone), (pendingQueue = current)) : (newBaseQueueLast = newBaseQueueLast.next = clone); updateExpirationTime > currentlyRenderingFiber$1.expirationTime && ((currentlyRenderingFiber$1.expirationTime = updateExpirationTime), @@ -3314,33 +3287,56 @@ function updateReducer(reducer) { null !== newBaseQueueLast && (newBaseQueueLast = newBaseQueueLast.next = { expirationTime: 1073741823, - suspenseConfig: _update.suspenseConfig, - action: _update.action, - eagerReducer: _update.eagerReducer, - eagerState: _update.eagerState, + suspenseConfig: update.suspenseConfig, + action: update.action, + eagerReducer: update.eagerReducer, + eagerState: update.eagerState, next: null }), markRenderEventTimeAndConfig( updateExpirationTime, - _update.suspenseConfig + update.suspenseConfig ), - (newState = - _update.eagerReducer === reducer - ? _update.eagerState - : reducer(newState, _update.action)); - _update = _update.next; - } while (null !== _update && _update !== _dispatch); + (current = + update.eagerReducer === reducer + ? update.eagerState + : reducer(current, update.action)); + update = update.next; + } while (null !== update && update !== baseQueue); null === newBaseQueueLast - ? (firstRenderPhaseUpdate = newState) + ? (pendingQueue = current) : (newBaseQueueLast.next = baseFirst); - is$1(newState, hook.memoizedState) || (didReceiveUpdate = !0); - hook.memoizedState = newState; - hook.baseState = firstRenderPhaseUpdate; + objectIs(current, hook.memoizedState) || (didReceiveUpdate = !0); + hook.memoizedState = current; + hook.baseState = pendingQueue; hook.baseQueue = newBaseQueueLast; - queue.lastRenderedState = newState; + queue.lastRenderedState = current; } return [hook.memoizedState, queue.dispatch]; } +function rerenderReducer(reducer) { + var hook = updateWorkInProgressHook(), + queue = hook.queue; + if (null === queue) + throw Error( + "Should have a queue. This is likely a bug in React. Please file an issue." + ); + queue.lastRenderedReducer = reducer; + var dispatch = queue.dispatch, + lastRenderPhaseUpdate = queue.pending, + newState = hook.memoizedState; + if (null !== lastRenderPhaseUpdate) { + queue.pending = null; + var update = (lastRenderPhaseUpdate = lastRenderPhaseUpdate.next); + do (newState = reducer(newState, update.action)), (update = update.next); + while (update !== lastRenderPhaseUpdate); + objectIs(newState, hook.memoizedState) || (didReceiveUpdate = !0); + hook.memoizedState = newState; + null === hook.baseQueue && (hook.baseState = newState); + queue.lastRenderedState = newState; + } + return [newState, dispatch]; +} function mountState(initialState) { var hook = mountWorkInProgressHook(); "function" === typeof initialState && (initialState = initialState()); @@ -3361,6 +3357,9 @@ function mountState(initialState) { function updateState(initialState) { return updateReducer(basicStateReducer, initialState); } +function rerenderState(initialState) { + return rerenderReducer(basicStateReducer, initialState); +} function pushEffect(tag, create, destroy, deps) { tag = { tag: tag, create: create, destroy: destroy, deps: deps, next: null }; create = currentlyRenderingFiber$1.updateQueue; @@ -3377,6 +3376,9 @@ function pushEffect(tag, create, destroy, deps) { (create.lastEffect = tag))); return tag; } +function updateRef() { + return updateWorkInProgressHook().memoizedState; +} function mountEffectImpl(fiberEffectTag, hookEffectTag, create, deps) { var hook = mountWorkInProgressHook(); currentlyRenderingFiber$1.effectTag |= fiberEffectTag; @@ -3408,6 +3410,9 @@ function mountEffect(create, deps) { function updateEffect(create, deps) { return updateEffectImpl(516, 192, create, deps); } +function updateLayoutEffect(create, deps) { + return updateEffectImpl(4, 36, create, deps); +} function imperativeHandleEffect(create, ref) { if ("function" === typeof ref) return ( @@ -3426,6 +3431,15 @@ function imperativeHandleEffect(create, ref) { } ); } +function updateImperativeHandle(ref, create, deps) { + deps = null !== deps && void 0 !== deps ? deps.concat([ref]) : null; + return updateEffectImpl( + 4, + 36, + imperativeHandleEffect.bind(null, create, ref), + deps + ); +} function mountDebugValue() {} function mountCallback(callback, deps) { mountWorkInProgressHook().memoizedState = [ @@ -3447,6 +3461,20 @@ function updateCallback(callback, deps) { hook.memoizedState = [callback, deps]; return callback; } +function updateMemo(nextCreate, deps) { + var hook = updateWorkInProgressHook(); + deps = void 0 === deps ? null : deps; + var prevState = hook.memoizedState; + if ( + null !== prevState && + null !== deps && + areHookInputsEqual(deps, prevState[1]) + ) + return prevState[0]; + nextCreate = nextCreate(); + hook.memoizedState = [nextCreate, deps]; + return nextCreate; +} function startTransition(setPending, config, callback) { var priorityLevel = getCurrentPriorityLevel(); runWithPriority(98 > priorityLevel ? 98 : priorityLevel, function() { @@ -3463,62 +3491,42 @@ function startTransition(setPending, config, callback) { }); } function dispatchAction(fiber, queue, action) { - if (!(25 > numberOfReRenders)) - throw Error( - "Too many re-renders. React limits the number of renders to prevent an infinite loop." - ); - var alternate = fiber.alternate; + var currentTime = requestCurrentTimeForUpdate(), + suspenseConfig = ReactCurrentBatchConfig.suspense; + currentTime = computeExpirationForFiber(currentTime, fiber, suspenseConfig); + suspenseConfig = { + expirationTime: currentTime, + suspenseConfig: suspenseConfig, + action: action, + eagerReducer: null, + eagerState: null, + next: null + }; + var pending = queue.pending; + null === pending + ? (suspenseConfig.next = suspenseConfig) + : ((suspenseConfig.next = pending.next), (pending.next = suspenseConfig)); + queue.pending = suspenseConfig; + pending = fiber.alternate; if ( fiber === currentlyRenderingFiber$1 || - (null !== alternate && alternate === currentlyRenderingFiber$1) + (null !== pending && pending === currentlyRenderingFiber$1) ) - if ( - ((didScheduleRenderPhaseUpdate = !0), - (fiber = { - expirationTime: renderExpirationTime$1, - suspenseConfig: null, - action: action, - eagerReducer: null, - eagerState: null, - next: null - }), - null === renderPhaseUpdates && (renderPhaseUpdates = new Map()), - (action = renderPhaseUpdates.get(queue)), - void 0 === action) - ) - renderPhaseUpdates.set(queue, fiber); - else { - for (queue = action; null !== queue.next; ) queue = queue.next; - queue.next = fiber; - } + (didScheduleRenderPhaseUpdate = !0), + (suspenseConfig.expirationTime = renderExpirationTime$1), + (currentlyRenderingFiber$1.expirationTime = renderExpirationTime$1); else { - var currentTime = requestCurrentTimeForUpdate(), - suspenseConfig = ReactCurrentBatchConfig.suspense; - currentTime = computeExpirationForFiber(currentTime, fiber, suspenseConfig); - suspenseConfig = { - expirationTime: currentTime, - suspenseConfig: suspenseConfig, - action: action, - eagerReducer: null, - eagerState: null, - next: null - }; - var pending = queue.pending; - null === pending - ? (suspenseConfig.next = suspenseConfig) - : ((suspenseConfig.next = pending.next), (pending.next = suspenseConfig)); - queue.pending = suspenseConfig; if ( 0 === fiber.expirationTime && - (null === alternate || 0 === alternate.expirationTime) && - ((alternate = queue.lastRenderedReducer), null !== alternate) + (null === pending || 0 === pending.expirationTime) && + ((pending = queue.lastRenderedReducer), null !== pending) ) try { var currentState = queue.lastRenderedState, - eagerState = alternate(currentState, action); - suspenseConfig.eagerReducer = alternate; + eagerState = pending(currentState, action); + suspenseConfig.eagerReducer = pending; suspenseConfig.eagerState = eagerState; - if (is$1(eagerState, currentState)) return; + if (objectIs(eagerState, currentState)) return; } catch (error) { } finally { } @@ -3627,36 +3635,11 @@ var ContextOnlyDispatcher = { useCallback: updateCallback, useContext: readContext, useEffect: updateEffect, - useImperativeHandle: function(ref, create, deps) { - deps = null !== deps && void 0 !== deps ? deps.concat([ref]) : null; - return updateEffectImpl( - 4, - 36, - imperativeHandleEffect.bind(null, create, ref), - deps - ); - }, - useLayoutEffect: function(create, deps) { - return updateEffectImpl(4, 36, create, deps); - }, - useMemo: function(nextCreate, deps) { - var hook = updateWorkInProgressHook(); - deps = void 0 === deps ? null : deps; - var prevState = hook.memoizedState; - if ( - null !== prevState && - null !== deps && - areHookInputsEqual(deps, prevState[1]) - ) - return prevState[0]; - nextCreate = nextCreate(); - hook.memoizedState = [nextCreate, deps]; - return nextCreate; - }, + useImperativeHandle: updateImperativeHandle, + useLayoutEffect: updateLayoutEffect, + useMemo: updateMemo, useReducer: updateReducer, - useRef: function() { - return updateWorkInProgressHook().memoizedState; - }, + useRef: updateRef, useState: updateState, useDebugValue: mountDebugValue, useResponder: createDeprecatedResponderListener, @@ -3692,6 +3675,51 @@ var ContextOnlyDispatcher = { ]; } }, + HooksDispatcherOnRerender = { + readContext: readContext, + useCallback: updateCallback, + useContext: readContext, + useEffect: updateEffect, + useImperativeHandle: updateImperativeHandle, + useLayoutEffect: updateLayoutEffect, + useMemo: updateMemo, + useReducer: rerenderReducer, + useRef: updateRef, + useState: rerenderState, + useDebugValue: mountDebugValue, + useResponder: createDeprecatedResponderListener, + useDeferredValue: function(value, config) { + var _rerenderState = rerenderState(value), + prevValue = _rerenderState[0], + setValue = _rerenderState[1]; + updateEffect( + function() { + var previousConfig = ReactCurrentBatchConfig$1.suspense; + ReactCurrentBatchConfig$1.suspense = + void 0 === config ? null : config; + try { + setValue(value); + } finally { + ReactCurrentBatchConfig$1.suspense = previousConfig; + } + }, + [value, config] + ); + return prevValue; + }, + useTransition: function(config) { + var _rerenderState2 = rerenderState(!1), + isPending = _rerenderState2[0]; + _rerenderState2 = _rerenderState2[1]; + return [ + updateCallback(startTransition.bind(null, _rerenderState2, config), [ + _rerenderState2, + config + ]), + isPending + ]; + } + }, now$1 = Scheduler.unstable_now, commitTime = 0, profilerStartTime = -1; @@ -4747,8 +4775,8 @@ updateHostComponent$1 = function(current, workInProgress, type, newProps) { ? cloneNodeWithNewProps(recyclableInstance, newProps) : cloneNode(recyclableInstance) : null !== newProps - ? cloneNodeWithNewChildrenAndProps(recyclableInstance, newProps) - : cloneNodeWithNewChildren(recyclableInstance), + ? cloneNodeWithNewChildrenAndProps(recyclableInstance, newProps) + : cloneNodeWithNewChildren(recyclableInstance), canonical: type.canonical }), (workInProgress.stateNode = type), @@ -5568,8 +5596,8 @@ function requestCurrentTimeForUpdate() { return (executionContext & (RenderContext | CommitContext)) !== NoContext ? 1073741821 - ((now() / 10) | 0) : 0 !== currentEventTime - ? currentEventTime - : (currentEventTime = 1073741821 - ((now() / 10) | 0)); + ? currentEventTime + : (currentEventTime = 1073741821 - ((now() / 10) | 0)); } function computeExpirationForFiber(currentTime, fiber, suspenseConfig) { fiber = fiber.mode; @@ -5679,9 +5707,10 @@ function getNextRootExpirationTimeToWorkOn(root) { if (0 !== lastExpiredTime) return lastExpiredTime; lastExpiredTime = root.firstPendingTime; if (!isRootSuspendedAtTime(root, lastExpiredTime)) return lastExpiredTime; - lastExpiredTime = root.lastPingedTime; + var lastPingedTime = root.lastPingedTime; root = root.nextKnownPendingLevel; - return lastExpiredTime > root ? lastExpiredTime : root; + root = lastPingedTime > root ? lastPingedTime : root; + return 2 >= root && lastExpiredTime !== root ? 0 : root; } function ensureRootIsScheduled(root) { if (0 !== root.lastExpiredTime) @@ -5857,35 +5886,34 @@ function performConcurrentWorkOnRoot(root, didTimeout) { 10 * (1073741821 - workInProgressRootLatestSuspenseTimeout) - now()) : 1073741823 === workInProgressRootLatestProcessedExpirationTime - ? (prevExecutionContext = 0) - : ((prevExecutionContext = - 10 * - (1073741821 - - workInProgressRootLatestProcessedExpirationTime) - - 5e3), - (prevDispatcher = now()), - (expirationTime = - 10 * (1073741821 - expirationTime) - prevDispatcher), - (prevExecutionContext = - prevDispatcher - prevExecutionContext), - 0 > prevExecutionContext && (prevExecutionContext = 0), - (prevExecutionContext = - (120 > prevExecutionContext - ? 120 - : 480 > prevExecutionContext - ? 480 - : 1080 > prevExecutionContext - ? 1080 - : 1920 > prevExecutionContext - ? 1920 - : 3e3 > prevExecutionContext - ? 3e3 - : 4320 > prevExecutionContext - ? 4320 - : 1960 * ceil(prevExecutionContext / 1960)) - - prevExecutionContext), - expirationTime < prevExecutionContext && - (prevExecutionContext = expirationTime)); + ? (prevExecutionContext = 0) + : ((prevExecutionContext = + 10 * + (1073741821 - + workInProgressRootLatestProcessedExpirationTime) - + 5e3), + (prevDispatcher = now()), + (expirationTime = + 10 * (1073741821 - expirationTime) - prevDispatcher), + (prevExecutionContext = prevDispatcher - prevExecutionContext), + 0 > prevExecutionContext && (prevExecutionContext = 0), + (prevExecutionContext = + (120 > prevExecutionContext + ? 120 + : 480 > prevExecutionContext + ? 480 + : 1080 > prevExecutionContext + ? 1080 + : 1920 > prevExecutionContext + ? 1920 + : 3e3 > prevExecutionContext + ? 3e3 + : 4320 > prevExecutionContext + ? 4320 + : 1960 * ceil(prevExecutionContext / 1960)) - + prevExecutionContext), + expirationTime < prevExecutionContext && + (prevExecutionContext = expirationTime)); if (10 < prevExecutionContext) { root.timeoutHandle = scheduleTimeout( commitRoot.bind(null, root), @@ -6044,7 +6072,20 @@ function handleError(root$jscomp$0, thrownValue) { do { try { resetContextDependencies(); - resetHooks(); + ReactCurrentDispatcher$1.current = ContextOnlyDispatcher; + if (didScheduleRenderPhaseUpdate) + for ( + var hook = currentlyRenderingFiber$1.memoizedState; + null !== hook; + + ) { + var queue = hook.queue; + null !== queue && (queue.pending = null); + hook = hook.next; + } + renderExpirationTime$1 = 0; + workInProgressHook = currentHook = currentlyRenderingFiber$1 = null; + didScheduleRenderPhaseUpdate = !1; if (null === workInProgress || null === workInProgress.return) return ( (workInProgressRootExitStatus = RootFatalErrored), @@ -6089,10 +6130,10 @@ function handleError(root$jscomp$0, thrownValue) { void 0 === props.fallback ? !1 : !0 !== props.unstable_avoidThisFallback - ? !0 - : hasInvisibleParentBoundary - ? !1 - : !0; + ? !0 + : hasInvisibleParentBoundary + ? !1 + : !0; } } if (JSCompiler_temp) { @@ -6703,8 +6744,6 @@ function pingSuspendedRoot(root, thenable, suspendedTime) { ((thenable = root.lastPingedTime), (0 !== thenable && thenable < suspendedTime) || ((root.lastPingedTime = suspendedTime), - root.finishedExpirationTime === suspendedTime && - ((root.finishedExpirationTime = 0), (root.finishedWork = null)), ensureRootIsScheduled(root), schedulePendingInteractions(root, suspendedTime))); } @@ -6847,7 +6886,8 @@ beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { void 0 === renderState.$$typeof ) { workInProgress.tag = 1; - resetHooks(); + workInProgress.memoizedState = null; + workInProgress.updateQueue = null; if (isContextProvider(updateExpirationTime)) { var hasContext = !0; pushContextProvider(workInProgress); @@ -7121,7 +7161,7 @@ beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { pushProvider(workInProgress, hasContext); if (null !== getDerivedStateFromProps) { var oldValue = getDerivedStateFromProps.value; - hasContext = is$1(oldValue, hasContext) + hasContext = objectIs(oldValue, hasContext) ? 0 : ("function" === typeof updateExpirationTime._calculateChangedBits ? updateExpirationTime._calculateChangedBits( @@ -7773,8 +7813,8 @@ function findNodeHandle(componentOrHandle) { return null == componentOrHandle ? componentOrHandle : componentOrHandle.canonical - ? componentOrHandle.canonical._nativeTag - : componentOrHandle._nativeTag; + ? componentOrHandle.canonical._nativeTag + : componentOrHandle._nativeTag; } batchedUpdatesImpl = function(fn, a) { var prevExecutionContext = executionContext; @@ -7897,8 +7937,8 @@ var roots = new Map(), return null == componentOrHandle ? componentOrHandle : componentOrHandle.canonical - ? componentOrHandle.canonical - : componentOrHandle; + ? componentOrHandle.canonical + : componentOrHandle; }, findNodeHandle: findNodeHandle, dispatchCommand: function(handle, command, args) { @@ -7940,6 +7980,9 @@ var roots = new Map(), return element; }, unmountComponentAtNode: function(containerTag) { + this.stopSurface(containerTag); + }, + stopSurface: function(containerTag) { var root = roots.get(containerTag); root && updateContainer(null, root, null, function() { @@ -8074,7 +8117,7 @@ var roots = new Map(), throw Error("getInspectorDataForViewTag() is not available in production"); }, bundleType: 0, - version: "16.12.0-experimental-19f6fe170", + version: "16.12.0-experimental-241c4467e", rendererPackageName: "react-native-renderer" }); var ReactFabric$2 = { default: ReactFabric }, diff --git a/Libraries/Renderer/implementations/ReactFabric-profiling.js b/Libraries/Renderer/implementations/ReactFabric-profiling.js index cf5e8cc3c3..e17402254e 100644 --- a/Libraries/Renderer/implementations/ReactFabric-profiling.js +++ b/Libraries/Renderer/implementations/ReactFabric-profiling.js @@ -350,8 +350,8 @@ function SyntheticEvent( ((targetInst = dispatchConfig[propName]) ? (this[propName] = targetInst(nativeEvent)) : "target" === propName - ? (this.target = nativeEventTarget) - : (this[propName] = nativeEvent[propName])); + ? (this.target = nativeEventTarget) + : (this[propName] = nativeEvent[propName])); this.isDefaultPrevented = (null != nativeEvent.defaultPrevented ? nativeEvent.defaultPrevented : !1 === nativeEvent.returnValue) @@ -564,10 +564,10 @@ function accumulate(current, next) { return null == current ? next : Array.isArray(current) - ? current.concat(next) - : Array.isArray(next) - ? [current].concat(next) - : [current, next]; + ? current.concat(next) + : Array.isArray(next) + ? [current].concat(next) + : [current, next]; } var responderInst = null, trackedTouchCount = 0; @@ -669,10 +669,10 @@ var eventTypes = { var shouldSetEventType = isStartish(topLevelType) ? eventTypes.startShouldSetResponder : isMoveish(topLevelType) - ? eventTypes.moveShouldSetResponder - : "topSelectionChange" === topLevelType - ? eventTypes.selectionChangeShouldSetResponder - : eventTypes.scrollShouldSetResponder; + ? eventTypes.moveShouldSetResponder + : "topSelectionChange" === topLevelType + ? eventTypes.selectionChangeShouldSetResponder + : eventTypes.scrollShouldSetResponder; if (responderInst) b: { var JSCompiler_temp = responderInst; @@ -826,10 +826,10 @@ var eventTypes = { (shouldSetEventType = shouldSetEventType ? eventTypes.responderStart : JSCompiler_temp - ? eventTypes.responderMove - : targetInst - ? eventTypes.responderEnd - : null) + ? eventTypes.responderMove + : targetInst + ? eventTypes.responderEnd + : null) ) (shouldSetEventType = ResponderSyntheticEvent.getPooled( shouldSetEventType, @@ -892,8 +892,8 @@ var eventTypes = { (topLevelType = shouldSetEventType ? eventTypes.responderTerminate : topLevelType - ? eventTypes.responderRelease - : null) + ? eventTypes.responderRelease + : null) ) (nativeEvent = ResponderSyntheticEvent.getPooled( topLevelType, @@ -1261,8 +1261,8 @@ function diffNestedProperty( return nextProp ? addNestedProperty(updatePayload, nextProp, validAttributes) : prevProp - ? clearNestedProperty(updatePayload, prevProp, validAttributes) - : updatePayload; + ? clearNestedProperty(updatePayload, prevProp, validAttributes) + : updatePayload; if (!Array.isArray(prevProp) && !Array.isArray(nextProp)) return diffProperties(updatePayload, prevProp, nextProp, validAttributes); if (Array.isArray(prevProp) && Array.isArray(nextProp)) { @@ -1857,18 +1857,18 @@ function inferPriorityFromExpirationTime(currentTime, expirationTime) { return 0 >= currentTime ? 99 : 250 >= currentTime - ? 98 - : 5250 >= currentTime - ? 97 - : 95; + ? 98 + : 5250 >= currentTime + ? 97 + : 95; } function is(x, y) { return (x === y && (0 !== x || 1 / x === 1 / y)) || (x !== x && y !== y); } -var is$1 = "function" === typeof Object.is ? Object.is : is, +var objectIs = "function" === typeof Object.is ? Object.is : is, hasOwnProperty = Object.prototype.hasOwnProperty; function shallowEqual(objA, objB) { - if (is$1(objA, objB)) return !0; + if (objectIs(objA, objB)) return !0; if ( "object" !== typeof objA || null === objA || @@ -1882,7 +1882,7 @@ function shallowEqual(objA, objB) { for (keysB = 0; keysB < keysA.length; keysB++) if ( !hasOwnProperty.call(objB, keysA[keysB]) || - !is$1(objA[keysA[keysB]], objB[keysA[keysB]]) + !objectIs(objA[keysA[keysB]], objB[keysA[keysB]]) ) return !1; return !0; @@ -2234,8 +2234,8 @@ function checkShouldComponentUpdate( return "function" === typeof workInProgress.shouldComponentUpdate ? workInProgress.shouldComponentUpdate(newProps, newState, nextContext) : ctor.prototype && ctor.prototype.isPureReactComponent - ? !shallowEqual(oldProps, newProps) || !shallowEqual(oldState, newState) - : !0; + ? !shallowEqual(oldProps, newProps) || !shallowEqual(oldState, newState) + : !0; } function constructClassInstance(workInProgress, ctor, props) { var isLegacyContextConsumer = !1, @@ -3130,9 +3130,7 @@ var ReactCurrentDispatcher$1 = ReactSharedInternals.ReactCurrentDispatcher, currentlyRenderingFiber$1 = null, currentHook = null, workInProgressHook = null, - didScheduleRenderPhaseUpdate = !1, - renderPhaseUpdates = null, - numberOfReRenders = 0; + didScheduleRenderPhaseUpdate = !1; function throwInvalidHookError() { throw Error( "Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons:\n1. You might have mismatching versions of React and the renderer (such as React DOM)\n2. You might be breaking the Rules of Hooks\n3. You might have more than one copy of React in the same app\nSee https://fb.me/react-invalid-hook-call for tips about how to debug and fix this problem." @@ -3141,7 +3139,7 @@ function throwInvalidHookError() { function areHookInputsEqual(nextDeps, prevDeps) { if (null === prevDeps) return !1; for (var i = 0; i < prevDeps.length && i < nextDeps.length; i++) - if (!is$1(nextDeps[i], prevDeps[i])) return !1; + if (!objectIs(nextDeps[i], prevDeps[i])) return !1; return !0; } function renderWithHooks( @@ -3162,36 +3160,32 @@ function renderWithHooks( ? HooksDispatcherOnMount : HooksDispatcherOnUpdate; current = Component(props, secondArg); - if (didScheduleRenderPhaseUpdate) { - do - (didScheduleRenderPhaseUpdate = !1), - (numberOfReRenders += 1), - (workInProgressHook = currentHook = null), - (workInProgress.updateQueue = null), - (ReactCurrentDispatcher$1.current = HooksDispatcherOnUpdate), - (current = Component(props, secondArg)); - while (didScheduleRenderPhaseUpdate); - renderPhaseUpdates = null; - numberOfReRenders = 0; + if (workInProgress.expirationTime === renderExpirationTime$1) { + nextRenderExpirationTime = 0; + do { + workInProgress.expirationTime = 0; + if (!(25 > nextRenderExpirationTime)) + throw Error( + "Too many re-renders. React limits the number of renders to prevent an infinite loop." + ); + nextRenderExpirationTime += 1; + workInProgressHook = currentHook = null; + workInProgress.updateQueue = null; + ReactCurrentDispatcher$1.current = HooksDispatcherOnRerender; + current = Component(props, secondArg); + } while (workInProgress.expirationTime === renderExpirationTime$1); } ReactCurrentDispatcher$1.current = ContextOnlyDispatcher; workInProgress = null !== currentHook && null !== currentHook.next; renderExpirationTime$1 = 0; workInProgressHook = currentHook = currentlyRenderingFiber$1 = null; + didScheduleRenderPhaseUpdate = !1; if (workInProgress) throw Error( "Rendered fewer hooks than expected. This may be caused by an accidental early return statement." ); return current; } -function resetHooks() { - ReactCurrentDispatcher$1.current = ContextOnlyDispatcher; - renderExpirationTime$1 = 0; - workInProgressHook = currentHook = currentlyRenderingFiber$1 = null; - didScheduleRenderPhaseUpdate = !1; - renderPhaseUpdates = null; - numberOfReRenders = 0; -} function mountWorkInProgressHook() { var hook = { memoizedState: null, @@ -3246,57 +3240,36 @@ function updateReducer(reducer) { "Should have a queue. This is likely a bug in React. Please file an issue." ); queue.lastRenderedReducer = reducer; - if (0 < numberOfReRenders) { - var _dispatch = queue.dispatch; - if (null !== renderPhaseUpdates) { - var firstRenderPhaseUpdate = renderPhaseUpdates.get(queue); - if (void 0 !== firstRenderPhaseUpdate) { - renderPhaseUpdates.delete(queue); - var newState = hook.memoizedState; - do - (newState = reducer(newState, firstRenderPhaseUpdate.action)), - (firstRenderPhaseUpdate = firstRenderPhaseUpdate.next); - while (null !== firstRenderPhaseUpdate); - is$1(newState, hook.memoizedState) || (didReceiveUpdate = !0); - hook.memoizedState = newState; - null === hook.baseQueue && (hook.baseState = newState); - queue.lastRenderedState = newState; - return [newState, _dispatch]; - } + var current = currentHook, + baseQueue = current.baseQueue, + pendingQueue = queue.pending; + if (null !== pendingQueue) { + if (null !== baseQueue) { + var baseFirst = baseQueue.next; + baseQueue.next = pendingQueue.next; + pendingQueue.next = baseFirst; } - return [hook.memoizedState, _dispatch]; - } - newState = currentHook; - _dispatch = newState.baseQueue; - firstRenderPhaseUpdate = queue.pending; - if (null !== firstRenderPhaseUpdate) { - if (null !== _dispatch) { - var baseFirst = _dispatch.next; - _dispatch.next = firstRenderPhaseUpdate.next; - firstRenderPhaseUpdate.next = baseFirst; - } - newState.baseQueue = _dispatch = firstRenderPhaseUpdate; + current.baseQueue = baseQueue = pendingQueue; queue.pending = null; } - if (null !== _dispatch) { - _dispatch = _dispatch.next; - newState = newState.baseState; - var newBaseQueueLast = (baseFirst = firstRenderPhaseUpdate = null), - _update = _dispatch; + if (null !== baseQueue) { + baseQueue = baseQueue.next; + current = current.baseState; + var newBaseQueueLast = (baseFirst = pendingQueue = null), + update = baseQueue; do { - var updateExpirationTime = _update.expirationTime; + var updateExpirationTime = update.expirationTime; if (updateExpirationTime < renderExpirationTime$1) { var clone = { - expirationTime: _update.expirationTime, - suspenseConfig: _update.suspenseConfig, - action: _update.action, - eagerReducer: _update.eagerReducer, - eagerState: _update.eagerState, + expirationTime: update.expirationTime, + suspenseConfig: update.suspenseConfig, + action: update.action, + eagerReducer: update.eagerReducer, + eagerState: update.eagerState, next: null }; null === newBaseQueueLast - ? ((baseFirst = newBaseQueueLast = clone), - (firstRenderPhaseUpdate = newState)) + ? ((baseFirst = newBaseQueueLast = clone), (pendingQueue = current)) : (newBaseQueueLast = newBaseQueueLast.next = clone); updateExpirationTime > currentlyRenderingFiber$1.expirationTime && ((currentlyRenderingFiber$1.expirationTime = updateExpirationTime), @@ -3305,33 +3278,56 @@ function updateReducer(reducer) { null !== newBaseQueueLast && (newBaseQueueLast = newBaseQueueLast.next = { expirationTime: 1073741823, - suspenseConfig: _update.suspenseConfig, - action: _update.action, - eagerReducer: _update.eagerReducer, - eagerState: _update.eagerState, + suspenseConfig: update.suspenseConfig, + action: update.action, + eagerReducer: update.eagerReducer, + eagerState: update.eagerState, next: null }), markRenderEventTimeAndConfig( updateExpirationTime, - _update.suspenseConfig + update.suspenseConfig ), - (newState = - _update.eagerReducer === reducer - ? _update.eagerState - : reducer(newState, _update.action)); - _update = _update.next; - } while (null !== _update && _update !== _dispatch); + (current = + update.eagerReducer === reducer + ? update.eagerState + : reducer(current, update.action)); + update = update.next; + } while (null !== update && update !== baseQueue); null === newBaseQueueLast - ? (firstRenderPhaseUpdate = newState) + ? (pendingQueue = current) : (newBaseQueueLast.next = baseFirst); - is$1(newState, hook.memoizedState) || (didReceiveUpdate = !0); - hook.memoizedState = newState; - hook.baseState = firstRenderPhaseUpdate; + objectIs(current, hook.memoizedState) || (didReceiveUpdate = !0); + hook.memoizedState = current; + hook.baseState = pendingQueue; hook.baseQueue = newBaseQueueLast; - queue.lastRenderedState = newState; + queue.lastRenderedState = current; } return [hook.memoizedState, queue.dispatch]; } +function rerenderReducer(reducer) { + var hook = updateWorkInProgressHook(), + queue = hook.queue; + if (null === queue) + throw Error( + "Should have a queue. This is likely a bug in React. Please file an issue." + ); + queue.lastRenderedReducer = reducer; + var dispatch = queue.dispatch, + lastRenderPhaseUpdate = queue.pending, + newState = hook.memoizedState; + if (null !== lastRenderPhaseUpdate) { + queue.pending = null; + var update = (lastRenderPhaseUpdate = lastRenderPhaseUpdate.next); + do (newState = reducer(newState, update.action)), (update = update.next); + while (update !== lastRenderPhaseUpdate); + objectIs(newState, hook.memoizedState) || (didReceiveUpdate = !0); + hook.memoizedState = newState; + null === hook.baseQueue && (hook.baseState = newState); + queue.lastRenderedState = newState; + } + return [newState, dispatch]; +} function mountState(initialState) { var hook = mountWorkInProgressHook(); "function" === typeof initialState && (initialState = initialState()); @@ -3352,6 +3348,9 @@ function mountState(initialState) { function updateState(initialState) { return updateReducer(basicStateReducer, initialState); } +function rerenderState(initialState) { + return rerenderReducer(basicStateReducer, initialState); +} function pushEffect(tag, create, destroy, deps) { tag = { tag: tag, create: create, destroy: destroy, deps: deps, next: null }; create = currentlyRenderingFiber$1.updateQueue; @@ -3368,6 +3367,9 @@ function pushEffect(tag, create, destroy, deps) { (create.lastEffect = tag))); return tag; } +function updateRef() { + return updateWorkInProgressHook().memoizedState; +} function mountEffectImpl(fiberEffectTag, hookEffectTag, create, deps) { var hook = mountWorkInProgressHook(); currentlyRenderingFiber$1.effectTag |= fiberEffectTag; @@ -3399,6 +3401,9 @@ function mountEffect(create, deps) { function updateEffect(create, deps) { return updateEffectImpl(516, 192, create, deps); } +function updateLayoutEffect(create, deps) { + return updateEffectImpl(4, 36, create, deps); +} function imperativeHandleEffect(create, ref) { if ("function" === typeof ref) return ( @@ -3417,6 +3422,15 @@ function imperativeHandleEffect(create, ref) { } ); } +function updateImperativeHandle(ref, create, deps) { + deps = null !== deps && void 0 !== deps ? deps.concat([ref]) : null; + return updateEffectImpl( + 4, + 36, + imperativeHandleEffect.bind(null, create, ref), + deps + ); +} function mountDebugValue() {} function mountCallback(callback, deps) { mountWorkInProgressHook().memoizedState = [ @@ -3438,6 +3452,20 @@ function updateCallback(callback, deps) { hook.memoizedState = [callback, deps]; return callback; } +function updateMemo(nextCreate, deps) { + var hook = updateWorkInProgressHook(); + deps = void 0 === deps ? null : deps; + var prevState = hook.memoizedState; + if ( + null !== prevState && + null !== deps && + areHookInputsEqual(deps, prevState[1]) + ) + return prevState[0]; + nextCreate = nextCreate(); + hook.memoizedState = [nextCreate, deps]; + return nextCreate; +} function startTransition(setPending, config, callback) { var priorityLevel = getCurrentPriorityLevel(); runWithPriority(98 > priorityLevel ? 98 : priorityLevel, function() { @@ -3454,62 +3482,42 @@ function startTransition(setPending, config, callback) { }); } function dispatchAction(fiber, queue, action) { - if (!(25 > numberOfReRenders)) - throw Error( - "Too many re-renders. React limits the number of renders to prevent an infinite loop." - ); - var alternate = fiber.alternate; + var currentTime = requestCurrentTimeForUpdate(), + suspenseConfig = ReactCurrentBatchConfig.suspense; + currentTime = computeExpirationForFiber(currentTime, fiber, suspenseConfig); + suspenseConfig = { + expirationTime: currentTime, + suspenseConfig: suspenseConfig, + action: action, + eagerReducer: null, + eagerState: null, + next: null + }; + var pending = queue.pending; + null === pending + ? (suspenseConfig.next = suspenseConfig) + : ((suspenseConfig.next = pending.next), (pending.next = suspenseConfig)); + queue.pending = suspenseConfig; + pending = fiber.alternate; if ( fiber === currentlyRenderingFiber$1 || - (null !== alternate && alternate === currentlyRenderingFiber$1) + (null !== pending && pending === currentlyRenderingFiber$1) ) - if ( - ((didScheduleRenderPhaseUpdate = !0), - (fiber = { - expirationTime: renderExpirationTime$1, - suspenseConfig: null, - action: action, - eagerReducer: null, - eagerState: null, - next: null - }), - null === renderPhaseUpdates && (renderPhaseUpdates = new Map()), - (action = renderPhaseUpdates.get(queue)), - void 0 === action) - ) - renderPhaseUpdates.set(queue, fiber); - else { - for (queue = action; null !== queue.next; ) queue = queue.next; - queue.next = fiber; - } + (didScheduleRenderPhaseUpdate = !0), + (suspenseConfig.expirationTime = renderExpirationTime$1), + (currentlyRenderingFiber$1.expirationTime = renderExpirationTime$1); else { - var currentTime = requestCurrentTimeForUpdate(), - suspenseConfig = ReactCurrentBatchConfig.suspense; - currentTime = computeExpirationForFiber(currentTime, fiber, suspenseConfig); - suspenseConfig = { - expirationTime: currentTime, - suspenseConfig: suspenseConfig, - action: action, - eagerReducer: null, - eagerState: null, - next: null - }; - var pending = queue.pending; - null === pending - ? (suspenseConfig.next = suspenseConfig) - : ((suspenseConfig.next = pending.next), (pending.next = suspenseConfig)); - queue.pending = suspenseConfig; if ( 0 === fiber.expirationTime && - (null === alternate || 0 === alternate.expirationTime) && - ((alternate = queue.lastRenderedReducer), null !== alternate) + (null === pending || 0 === pending.expirationTime) && + ((pending = queue.lastRenderedReducer), null !== pending) ) try { var currentState = queue.lastRenderedState, - eagerState = alternate(currentState, action); - suspenseConfig.eagerReducer = alternate; + eagerState = pending(currentState, action); + suspenseConfig.eagerReducer = pending; suspenseConfig.eagerState = eagerState; - if (is$1(eagerState, currentState)) return; + if (objectIs(eagerState, currentState)) return; } catch (error) { } finally { } @@ -3618,36 +3626,11 @@ var ContextOnlyDispatcher = { useCallback: updateCallback, useContext: readContext, useEffect: updateEffect, - useImperativeHandle: function(ref, create, deps) { - deps = null !== deps && void 0 !== deps ? deps.concat([ref]) : null; - return updateEffectImpl( - 4, - 36, - imperativeHandleEffect.bind(null, create, ref), - deps - ); - }, - useLayoutEffect: function(create, deps) { - return updateEffectImpl(4, 36, create, deps); - }, - useMemo: function(nextCreate, deps) { - var hook = updateWorkInProgressHook(); - deps = void 0 === deps ? null : deps; - var prevState = hook.memoizedState; - if ( - null !== prevState && - null !== deps && - areHookInputsEqual(deps, prevState[1]) - ) - return prevState[0]; - nextCreate = nextCreate(); - hook.memoizedState = [nextCreate, deps]; - return nextCreate; - }, + useImperativeHandle: updateImperativeHandle, + useLayoutEffect: updateLayoutEffect, + useMemo: updateMemo, useReducer: updateReducer, - useRef: function() { - return updateWorkInProgressHook().memoizedState; - }, + useRef: updateRef, useState: updateState, useDebugValue: mountDebugValue, useResponder: createDeprecatedResponderListener, @@ -3683,6 +3666,51 @@ var ContextOnlyDispatcher = { ]; } }, + HooksDispatcherOnRerender = { + readContext: readContext, + useCallback: updateCallback, + useContext: readContext, + useEffect: updateEffect, + useImperativeHandle: updateImperativeHandle, + useLayoutEffect: updateLayoutEffect, + useMemo: updateMemo, + useReducer: rerenderReducer, + useRef: updateRef, + useState: rerenderState, + useDebugValue: mountDebugValue, + useResponder: createDeprecatedResponderListener, + useDeferredValue: function(value, config) { + var _rerenderState = rerenderState(value), + prevValue = _rerenderState[0], + setValue = _rerenderState[1]; + updateEffect( + function() { + var previousConfig = ReactCurrentBatchConfig$1.suspense; + ReactCurrentBatchConfig$1.suspense = + void 0 === config ? null : config; + try { + setValue(value); + } finally { + ReactCurrentBatchConfig$1.suspense = previousConfig; + } + }, + [value, config] + ); + return prevValue; + }, + useTransition: function(config) { + var _rerenderState2 = rerenderState(!1), + isPending = _rerenderState2[0]; + _rerenderState2 = _rerenderState2[1]; + return [ + updateCallback(startTransition.bind(null, _rerenderState2, config), [ + _rerenderState2, + config + ]), + isPending + ]; + } + }, now$1 = Scheduler.unstable_now, commitTime = 0, profilerStartTime = -1; @@ -4738,8 +4766,8 @@ updateHostComponent$1 = function(current, workInProgress, type, newProps) { ? cloneNodeWithNewProps(recyclableInstance, newProps) : cloneNode(recyclableInstance) : null !== newProps - ? cloneNodeWithNewChildrenAndProps(recyclableInstance, newProps) - : cloneNodeWithNewChildren(recyclableInstance), + ? cloneNodeWithNewChildrenAndProps(recyclableInstance, newProps) + : cloneNodeWithNewChildren(recyclableInstance), canonical: type.canonical }), (workInProgress.stateNode = type), @@ -5559,8 +5587,8 @@ function requestCurrentTimeForUpdate() { return (executionContext & (RenderContext | CommitContext)) !== NoContext ? 1073741821 - ((now() / 10) | 0) : 0 !== currentEventTime - ? currentEventTime - : (currentEventTime = 1073741821 - ((now() / 10) | 0)); + ? currentEventTime + : (currentEventTime = 1073741821 - ((now() / 10) | 0)); } function computeExpirationForFiber(currentTime, fiber, suspenseConfig) { fiber = fiber.mode; @@ -5670,9 +5698,10 @@ function getNextRootExpirationTimeToWorkOn(root) { if (0 !== lastExpiredTime) return lastExpiredTime; lastExpiredTime = root.firstPendingTime; if (!isRootSuspendedAtTime(root, lastExpiredTime)) return lastExpiredTime; - lastExpiredTime = root.lastPingedTime; + var lastPingedTime = root.lastPingedTime; root = root.nextKnownPendingLevel; - return lastExpiredTime > root ? lastExpiredTime : root; + root = lastPingedTime > root ? lastPingedTime : root; + return 2 >= root && lastExpiredTime !== root ? 0 : root; } function ensureRootIsScheduled(root) { if (0 !== root.lastExpiredTime) @@ -5848,35 +5877,34 @@ function performConcurrentWorkOnRoot(root, didTimeout) { 10 * (1073741821 - workInProgressRootLatestSuspenseTimeout) - now()) : 1073741823 === workInProgressRootLatestProcessedExpirationTime - ? (prevExecutionContext = 0) - : ((prevExecutionContext = - 10 * - (1073741821 - - workInProgressRootLatestProcessedExpirationTime) - - 5e3), - (prevDispatcher = now()), - (expirationTime = - 10 * (1073741821 - expirationTime) - prevDispatcher), - (prevExecutionContext = - prevDispatcher - prevExecutionContext), - 0 > prevExecutionContext && (prevExecutionContext = 0), - (prevExecutionContext = - (120 > prevExecutionContext - ? 120 - : 480 > prevExecutionContext - ? 480 - : 1080 > prevExecutionContext - ? 1080 - : 1920 > prevExecutionContext - ? 1920 - : 3e3 > prevExecutionContext - ? 3e3 - : 4320 > prevExecutionContext - ? 4320 - : 1960 * ceil(prevExecutionContext / 1960)) - - prevExecutionContext), - expirationTime < prevExecutionContext && - (prevExecutionContext = expirationTime)); + ? (prevExecutionContext = 0) + : ((prevExecutionContext = + 10 * + (1073741821 - + workInProgressRootLatestProcessedExpirationTime) - + 5e3), + (prevDispatcher = now()), + (expirationTime = + 10 * (1073741821 - expirationTime) - prevDispatcher), + (prevExecutionContext = prevDispatcher - prevExecutionContext), + 0 > prevExecutionContext && (prevExecutionContext = 0), + (prevExecutionContext = + (120 > prevExecutionContext + ? 120 + : 480 > prevExecutionContext + ? 480 + : 1080 > prevExecutionContext + ? 1080 + : 1920 > prevExecutionContext + ? 1920 + : 3e3 > prevExecutionContext + ? 3e3 + : 4320 > prevExecutionContext + ? 4320 + : 1960 * ceil(prevExecutionContext / 1960)) - + prevExecutionContext), + expirationTime < prevExecutionContext && + (prevExecutionContext = expirationTime)); if (10 < prevExecutionContext) { root.timeoutHandle = scheduleTimeout( commitRoot.bind(null, root), @@ -6035,7 +6063,20 @@ function handleError(root$jscomp$0, thrownValue) { do { try { resetContextDependencies(); - resetHooks(); + ReactCurrentDispatcher$1.current = ContextOnlyDispatcher; + if (didScheduleRenderPhaseUpdate) + for ( + var hook = currentlyRenderingFiber$1.memoizedState; + null !== hook; + + ) { + var queue = hook.queue; + null !== queue && (queue.pending = null); + hook = hook.next; + } + renderExpirationTime$1 = 0; + workInProgressHook = currentHook = currentlyRenderingFiber$1 = null; + didScheduleRenderPhaseUpdate = !1; if (null === workInProgress || null === workInProgress.return) return ( (workInProgressRootExitStatus = RootFatalErrored), @@ -6080,10 +6121,10 @@ function handleError(root$jscomp$0, thrownValue) { void 0 === props.fallback ? !1 : !0 !== props.unstable_avoidThisFallback - ? !0 - : hasInvisibleParentBoundary - ? !1 - : !0; + ? !0 + : hasInvisibleParentBoundary + ? !1 + : !0; } } if (JSCompiler_temp) { @@ -6694,8 +6735,6 @@ function pingSuspendedRoot(root, thenable, suspendedTime) { ((thenable = root.lastPingedTime), (0 !== thenable && thenable < suspendedTime) || ((root.lastPingedTime = suspendedTime), - root.finishedExpirationTime === suspendedTime && - ((root.finishedExpirationTime = 0), (root.finishedWork = null)), ensureRootIsScheduled(root), schedulePendingInteractions(root, suspendedTime))); } @@ -6838,7 +6877,8 @@ beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { void 0 === renderState.$$typeof ) { workInProgress.tag = 1; - resetHooks(); + workInProgress.memoizedState = null; + workInProgress.updateQueue = null; if (isContextProvider(updateExpirationTime)) { var hasContext = !0; pushContextProvider(workInProgress); @@ -7112,7 +7152,7 @@ beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { pushProvider(workInProgress, hasContext); if (null !== getDerivedStateFromProps) { var oldValue = getDerivedStateFromProps.value; - hasContext = is$1(oldValue, hasContext) + hasContext = objectIs(oldValue, hasContext) ? 0 : ("function" === typeof updateExpirationTime._calculateChangedBits ? updateExpirationTime._calculateChangedBits( @@ -7764,8 +7804,8 @@ function findNodeHandle(componentOrHandle) { return null == componentOrHandle ? componentOrHandle : componentOrHandle.canonical - ? componentOrHandle.canonical._nativeTag - : componentOrHandle._nativeTag; + ? componentOrHandle.canonical._nativeTag + : componentOrHandle._nativeTag; } batchedUpdatesImpl = function(fn, a) { var prevExecutionContext = executionContext; @@ -7888,8 +7928,8 @@ var roots = new Map(), return null == componentOrHandle ? componentOrHandle : componentOrHandle.canonical - ? componentOrHandle.canonical - : componentOrHandle; + ? componentOrHandle.canonical + : componentOrHandle; }, findNodeHandle: findNodeHandle, dispatchCommand: function(handle, command, args) { @@ -7931,6 +7971,9 @@ var roots = new Map(), return element; }, unmountComponentAtNode: function(containerTag) { + this.stopSurface(containerTag); + }, + stopSurface: function(containerTag) { var root = roots.get(containerTag); root && updateContainer(null, root, null, function() { @@ -8065,7 +8108,7 @@ var roots = new Map(), throw Error("getInspectorDataForViewTag() is not available in production"); }, bundleType: 0, - version: "16.12.0-19f6fe170", + version: "16.12.0-241c4467e", rendererPackageName: "react-native-renderer" }); var ReactFabric$2 = { default: ReactFabric }, diff --git a/Libraries/Renderer/implementations/ReactNativeRenderer-dev.fb.js b/Libraries/Renderer/implementations/ReactNativeRenderer-dev.fb.js index ef0fe9a63c..16f6ce8d34 100644 --- a/Libraries/Renderer/implementations/ReactNativeRenderer-dev.fb.js +++ b/Libraries/Renderer/implementations/ReactNativeRenderer-dev.fb.js @@ -687,14 +687,14 @@ var validateEventDispatches; var listenersLen = listenersIsArr ? dispatchListeners.length : dispatchListeners - ? 1 - : 0; + ? 1 + : 0; var instancesIsArr = Array.isArray(dispatchInstances); var instancesLen = instancesIsArr ? dispatchInstances.length : dispatchInstances - ? 1 - : 0; + ? 1 + : 0; if (instancesIsArr !== listenersIsArr || instancesLen !== listenersLen) { error("EventPluginUtils: Invalid `event`."); @@ -2262,10 +2262,10 @@ function setResponderAndExtractTransfer( var shouldSetEventType = isStartish(topLevelType) ? eventTypes.startShouldSetResponder : isMoveish(topLevelType) - ? eventTypes.moveShouldSetResponder - : topLevelType === TOP_SELECTION_CHANGE - ? eventTypes.selectionChangeShouldSetResponder - : eventTypes.scrollShouldSetResponder; // TODO: stop one short of the current responder. + ? eventTypes.moveShouldSetResponder + : topLevelType === TOP_SELECTION_CHANGE + ? eventTypes.selectionChangeShouldSetResponder + : eventTypes.scrollShouldSetResponder; // TODO: stop one short of the current responder. var bubbleShouldSetFrom = !responderInst ? targetInst @@ -2469,10 +2469,10 @@ var ResponderEventPlugin = { var incrementalTouch = isResponderTouchStart ? eventTypes.responderStart : isResponderTouchMove - ? eventTypes.responderMove - : isResponderTouchEnd - ? eventTypes.responderEnd - : null; + ? eventTypes.responderMove + : isResponderTouchEnd + ? eventTypes.responderEnd + : null; if (incrementalTouch) { var gesture = ResponderSyntheticEvent.getPooled( @@ -2496,8 +2496,8 @@ var ResponderEventPlugin = { var finalTouch = isResponderTerminate ? eventTypes.responderTerminate : isResponderRelease - ? eventTypes.responderRelease - : null; + ? eventTypes.responderRelease + : null; if (finalTouch) { var finalEvent = ResponderSyntheticEvent.getPooled( @@ -2632,7 +2632,8 @@ var warnAboutDefaultPropsOnFunctionComponents = false; var warnAboutStringRefs = false; var disableLegacyContext = false; var disableSchedulerTimeoutBasedOnReactExpirationTime = false; -var enableTrainModelFix = false; +var enableTrainModelFix = true; + // Only used in www builds. // Flow magic to verify the exports of this file match the original version. @@ -5855,7 +5856,7 @@ function is(x, y) { ); } -var is$1 = typeof Object.is === "function" ? Object.is : is; +var objectIs = typeof Object.is === "function" ? Object.is : is; var hasOwnProperty = Object.prototype.hasOwnProperty; /** @@ -5865,7 +5866,7 @@ var hasOwnProperty = Object.prototype.hasOwnProperty; */ function shallowEqual(objA, objB) { - if (is$1(objA, objB)) { + if (objectIs(objA, objB)) { return true; } @@ -5888,7 +5889,7 @@ function shallowEqual(objA, objB) { for (var i = 0; i < keysA.length; i++) { if ( !hasOwnProperty.call(objB, keysA[i]) || - !is$1(objA[keysA[i]], objB[keysA[i]]) + !objectIs(objA[keysA[i]], objB[keysA[i]]) ) { return false; } @@ -6205,13 +6206,18 @@ var ReactStrictModeWarnings = { ReactStrictModeWarnings.flushLegacyContextWarning = function() { pendingLegacyContextWarning.forEach(function(fiberArray, strictRoot) { + if (fiberArray.length === 0) { + return; + } + + var firstFiber = fiberArray[0]; var uniqueNames = new Set(); fiberArray.forEach(function(fiber) { uniqueNames.add(getComponentName(fiber.type) || "Component"); didWarnAboutLegacyContext.add(fiber.type); }); var sortedNames = setToSortedString(uniqueNames); - var strictRootComponentStack = getStackByFiberInDevAndProd(strictRoot); + var firstComponentStack = getStackByFiberInDevAndProd(firstFiber); error( "Legacy context API has been detected within a strict-mode tree." + @@ -6221,7 +6227,7 @@ var ReactStrictModeWarnings = { "\n\nLearn more about this warning here: https://fb.me/react-legacy-context" + "%s", sortedNames, - strictRootComponentStack + firstComponentStack ); }); }; @@ -6791,7 +6797,7 @@ function popProvider(providerFiber) { } } function calculateChangedBits(context, newValue, oldValue) { - if (is$1(oldValue, newValue)) { + if (objectIs(oldValue, newValue)) { // No change return 0; } else { @@ -8752,7 +8758,16 @@ function coerceRef(returnFiber, current$$1, element) { { // TODO: Clean this up once we turn on the string ref warning for // everyone, because the strict mode case will no longer be relevant - if (returnFiber.mode & StrictMode || warnAboutStringRefs) { + if ( + (returnFiber.mode & StrictMode || warnAboutStringRefs) && // We warn in ReactElement.js if owner and self are equal for string refs + // because these cannot be automatically converted to an arrow function + // using a codemod. Therefore, we don't have to warn about string refs again. + !( + element._owner && + element._self && + element._owner.stateNode !== element._self + ) + ) { var componentName = getComponentName(returnFiber.type) || "Component"; if (!didWarnAboutStringRefs[componentName]) { @@ -10614,20 +10629,12 @@ var currentlyRenderingFiber$1 = null; // Hooks are stored as a linked list on th // work-in-progress fiber. var currentHook = null; -var workInProgressHook = null; // Updates scheduled during render will trigger an immediate re-render at the -// end of the current pass. We can't store these updates on the normal queue, -// because if the work is aborted, they should be discarded. Because this is -// a relatively rare case, we also don't want to add an additional field to -// either the hook or queue object types. So we store them in a lazily create -// map of queue -> render-phase updates, which are discarded once the component -// completes without re-rendering. -// Whether an update was scheduled during the currently executing render pass. +var workInProgressHook = null; // Whether an update was scheduled at any point during the render phase. This +// does not get reset if we do another render pass; only when we're completely +// finished evaluating this component. This is an optimization so we know +// whether we need to clear render phase updates after a throw. -var didScheduleRenderPhaseUpdate = false; // Lazily created map of render-phase updates - -var renderPhaseUpdates = null; // Counter to prevent infinite loops. - -var numberOfReRenders = 0; +var didScheduleRenderPhaseUpdate = false; var RE_RENDER_LIMIT = 25; // In DEV, this is the name of the currently executing primitive hook var currentHookNameInDev = null; // In DEV, this list ensures that hooks are called in the same order between renders. @@ -10770,7 +10777,7 @@ function areHookInputsEqual(nextDeps, prevDeps) { } for (var i = 0; i < prevDeps.length && i < nextDeps.length; i++) { - if (is$1(nextDeps[i], prevDeps[i])) { + if (objectIs(nextDeps[i], prevDeps[i])) { continue; } @@ -10805,8 +10812,6 @@ function renderWithHooks( // currentHook = null; // workInProgressHook = null; // didScheduleRenderPhaseUpdate = false; - // renderPhaseUpdates = null; - // numberOfReRenders = 0; // TODO Warn if no hooks are used at all during mount, then some are used during update. // Currently we will identify the update render as a mount because memoizedState === null. // This is tricky because it's valid for certain types of components (e.g. React.lazy) @@ -10829,11 +10834,22 @@ function renderWithHooks( } } - var children = Component(props, secondArg); + var children = Component(props, secondArg); // Check if there was a render phase update + + if (workInProgress.expirationTime === renderExpirationTime$1) { + // Keep rendering in a loop for as long as render phase updates continue to + // be scheduled. Use a counter to prevent infinite loops. + var numberOfReRenders = 0; - if (didScheduleRenderPhaseUpdate) { do { - didScheduleRenderPhaseUpdate = false; + workInProgress.expirationTime = NoWork; + + if (!(numberOfReRenders < RE_RENDER_LIMIT)) { + throw Error( + "Too many re-renders. React limits the number of renders to prevent an infinite loop." + ); + } + numberOfReRenders += 1; { @@ -10851,12 +10867,9 @@ function renderWithHooks( hookTypesUpdateIndexDev = -1; } - ReactCurrentDispatcher$1.current = HooksDispatcherOnUpdateInDEV; + ReactCurrentDispatcher$1.current = HooksDispatcherOnRerenderInDEV; children = Component(props, secondArg); - } while (didScheduleRenderPhaseUpdate); - - renderPhaseUpdates = null; - numberOfReRenders = 0; + } while (workInProgress.expirationTime === renderExpirationTime$1); } // We can assume the previous dispatcher is always this one, since we set it // at the beginning of the render phase and there's no re-entrancy. @@ -10877,10 +10890,9 @@ function renderWithHooks( currentHookNameInDev = null; hookTypesDev = null; hookTypesUpdateIndexDev = -1; - } // These were reset above - // didScheduleRenderPhaseUpdate = false; - // renderPhaseUpdates = null; - // numberOfReRenders = 0; + } + + didScheduleRenderPhaseUpdate = false; if (!!didRenderTooFewHooks) { throw Error( @@ -10898,12 +10910,32 @@ function bailoutHooks(current, workInProgress, expirationTime) { current.expirationTime = NoWork; } } -function resetHooks() { +function resetHooksAfterThrow() { // We can assume the previous dispatcher is always this one, since we set it // at the beginning of the render phase and there's no re-entrancy. - ReactCurrentDispatcher$1.current = ContextOnlyDispatcher; // This is used to reset the state of this module when a component throws. - // It's also called inside mountIndeterminateComponent if we determine the - // component is a module-style component. + ReactCurrentDispatcher$1.current = ContextOnlyDispatcher; + + if (didScheduleRenderPhaseUpdate) { + // There were render phase updates. These are only valid for this render + // phase, which we are now aborting. Remove the updates from the queues so + // they do not persist to the next render. Do not remove updates from hooks + // that weren't processed. + // + // Only reset the updates from the queue if it has a clone. If it does + // not have a clone, that means it wasn't processed, and the updates were + // scheduled before we entered the render phase. + var hook = currentlyRenderingFiber$1.memoizedState; + + while (hook !== null) { + var queue = hook.queue; + + if (queue !== null) { + queue.pending = null; + } + + hook = hook.next; + } + } renderExpirationTime$1 = NoWork; currentlyRenderingFiber$1 = null; @@ -10917,8 +10949,6 @@ function resetHooks() { } didScheduleRenderPhaseUpdate = false; - renderPhaseUpdates = null; - numberOfReRenders = 0; } function mountWorkInProgressHook() { @@ -11008,6 +11038,7 @@ function createFunctionComponentUpdateQueue() { } function basicStateReducer(state, action) { + // $FlowFixMe: Flow doesn't like mixed types return typeof action === "function" ? action(state) : action; } @@ -11047,52 +11078,6 @@ function updateReducer(reducer, initialArg, init) { } queue.lastRenderedReducer = reducer; - - if (numberOfReRenders > 0) { - // This is a re-render. Apply the new render phase updates to the previous - // work-in-progress hook. - var _dispatch = queue.dispatch; - - if (renderPhaseUpdates !== null) { - // Render phase updates are stored in a map of queue -> linked list - var firstRenderPhaseUpdate = renderPhaseUpdates.get(queue); - - if (firstRenderPhaseUpdate !== undefined) { - renderPhaseUpdates.delete(queue); - var newState = hook.memoizedState; - var update = firstRenderPhaseUpdate; - - do { - // Process this render phase update. We don't have to check the - // priority because it will always be the same as the current - // render's. - var action = update.action; - newState = reducer(newState, action); - update = update.next; - } while (update !== null); // Mark that the fiber performed work, but only if the new state is - // different from the current state. - - if (!is$1(newState, hook.memoizedState)) { - markWorkInProgressReceivedUpdate(); - } - - hook.memoizedState = newState; // Don't persist the state accumulated from the render phase updates to - // the base state unless the queue is empty. - // TODO: Not sure if this is the desired semantics, but it's what we - // do for gDSFP. I can't remember why. - - if (hook.baseQueue === null) { - hook.baseState = newState; - } - - queue.lastRenderedState = newState; - return [newState, _dispatch]; - } - } - - return [hook.memoizedState, _dispatch]; - } - var current = currentHook; // The last rebase update that is NOT part of the base state. var baseQueue = current.baseQueue; // The last pending update that hasn't been processed yet. @@ -11117,31 +11102,31 @@ function updateReducer(reducer, initialArg, init) { if (baseQueue !== null) { // We have a queue to process. var first = baseQueue.next; - var _newState = current.baseState; + var newState = current.baseState; var newBaseState = null; var newBaseQueueFirst = null; var newBaseQueueLast = null; - var _update = first; + var update = first; do { - var updateExpirationTime = _update.expirationTime; + var updateExpirationTime = update.expirationTime; if (updateExpirationTime < renderExpirationTime$1) { // Priority is insufficient. Skip this update. If this is the first // skipped update, the previous update/state is the new base // update/state. var clone = { - expirationTime: _update.expirationTime, - suspenseConfig: _update.suspenseConfig, - action: _update.action, - eagerReducer: _update.eagerReducer, - eagerState: _update.eagerState, + expirationTime: update.expirationTime, + suspenseConfig: update.suspenseConfig, + action: update.action, + eagerReducer: update.eagerReducer, + eagerState: update.eagerState, next: null }; if (newBaseQueueLast === null) { newBaseQueueFirst = newBaseQueueLast = clone; - newBaseState = _newState; + newBaseState = newState; } else { newBaseQueueLast = newBaseQueueLast.next = clone; } // Update the remaining priority in the queue. @@ -11156,10 +11141,10 @@ function updateReducer(reducer, initialArg, init) { var _clone = { expirationTime: Sync, // This update is going to be committed so we never want uncommit it. - suspenseConfig: _update.suspenseConfig, - action: _update.action, - eagerReducer: _update.eagerReducer, - eagerState: _update.eagerState, + suspenseConfig: update.suspenseConfig, + action: update.action, + eagerReducer: update.eagerReducer, + eagerState: update.eagerState, next: null }; newBaseQueueLast = newBaseQueueLast.next = _clone; @@ -11172,47 +11157,100 @@ function updateReducer(reducer, initialArg, init) { markRenderEventTimeAndConfig( updateExpirationTime, - _update.suspenseConfig + update.suspenseConfig ); // Process this update. - if (_update.eagerReducer === reducer) { + if (update.eagerReducer === reducer) { // If this update was processed eagerly, and its reducer matches the // current reducer, we can use the eagerly computed state. - _newState = _update.eagerState; + newState = update.eagerState; } else { - var _action = _update.action; - _newState = reducer(_newState, _action); + var action = update.action; + newState = reducer(newState, action); } } - _update = _update.next; - } while (_update !== null && _update !== first); + update = update.next; + } while (update !== null && update !== first); if (newBaseQueueLast === null) { - newBaseState = _newState; + newBaseState = newState; } else { newBaseQueueLast.next = newBaseQueueFirst; } // Mark that the fiber performed work, but only if the new state is // different from the current state. - if (!is$1(_newState, hook.memoizedState)) { + if (!objectIs(newState, hook.memoizedState)) { markWorkInProgressReceivedUpdate(); } - hook.memoizedState = _newState; + hook.memoizedState = newState; hook.baseState = newBaseState; hook.baseQueue = newBaseQueueLast; - queue.lastRenderedState = _newState; + queue.lastRenderedState = newState; } var dispatch = queue.dispatch; return [hook.memoizedState, dispatch]; } +function rerenderReducer(reducer, initialArg, init) { + var hook = updateWorkInProgressHook(); + var queue = hook.queue; + + if (!(queue !== null)) { + throw Error( + "Should have a queue. This is likely a bug in React. Please file an issue." + ); + } + + queue.lastRenderedReducer = reducer; // This is a re-render. Apply the new render phase updates to the previous + // work-in-progress hook. + + var dispatch = queue.dispatch; + var lastRenderPhaseUpdate = queue.pending; + var newState = hook.memoizedState; + + if (lastRenderPhaseUpdate !== null) { + // The queue doesn't persist past this render pass. + queue.pending = null; + var firstRenderPhaseUpdate = lastRenderPhaseUpdate.next; + var update = firstRenderPhaseUpdate; + + do { + // Process this render phase update. We don't have to check the + // priority because it will always be the same as the current + // render's. + var action = update.action; + newState = reducer(newState, action); + update = update.next; + } while (update !== firstRenderPhaseUpdate); // Mark that the fiber performed work, but only if the new state is + // different from the current state. + + if (!objectIs(newState, hook.memoizedState)) { + markWorkInProgressReceivedUpdate(); + } + + hook.memoizedState = newState; // Don't persist the state accumulated from the render phase updates to + // the base state unless the queue is empty. + // TODO: Not sure if this is the desired semantics, but it's what we + // do for gDSFP. I can't remember why. + + if (hook.baseQueue === null) { + hook.baseState = newState; + } + + queue.lastRenderedState = newState; + } + + return [newState, dispatch]; +} + function mountState(initialState) { var hook = mountWorkInProgressHook(); if (typeof initialState === "function") { + // $FlowFixMe: Flow doesn't like mixed types initialState = initialState(); } @@ -11235,6 +11273,10 @@ function updateState(initialState) { return updateReducer(basicStateReducer, initialState); } +function rerenderState(initialState) { + return rerenderReducer(basicStateReducer, initialState); +} + function pushEffect(tag, create, destroy, deps) { var effect = { tag: tag, @@ -11534,6 +11576,27 @@ function updateDeferredValue(value, config) { return prevValue; } +function rerenderDeferredValue(value, config) { + var _rerenderState = rerenderState(value), + prevValue = _rerenderState[0], + setValue = _rerenderState[1]; + + updateEffect( + function() { + var previousConfig = ReactCurrentBatchConfig$1.suspense; + ReactCurrentBatchConfig$1.suspense = config === undefined ? null : config; + + try { + setValue(value); + } finally { + ReactCurrentBatchConfig$1.suspense = previousConfig; + } + }, + [value, config] + ); + return prevValue; +} + function startTransition(setPending, config, callback) { var priorityLevel = getCurrentPriorityLevel(); runWithPriority( @@ -11582,13 +11645,19 @@ function updateTransition(config) { return [start, isPending]; } -function dispatchAction(fiber, queue, action) { - if (!(numberOfReRenders < RE_RENDER_LIMIT)) { - throw Error( - "Too many re-renders. React limits the number of renders to prevent an infinite loop." - ); - } +function rerenderTransition(config) { + var _rerenderState2 = rerenderState(false), + isPending = _rerenderState2[0], + setPending = _rerenderState2[1]; + var start = updateCallback(startTransition.bind(null, setPending, config), [ + setPending, + config + ]); + return [start, isPending]; +} + +function dispatchAction(fiber, queue, action) { { if (typeof arguments[3] === "function") { error( @@ -11599,6 +11668,37 @@ function dispatchAction(fiber, queue, action) { } } + var currentTime = requestCurrentTimeForUpdate(); + var suspenseConfig = requestCurrentSuspenseConfig(); + var expirationTime = computeExpirationForFiber( + currentTime, + fiber, + suspenseConfig + ); + var update = { + expirationTime: expirationTime, + suspenseConfig: suspenseConfig, + action: action, + eagerReducer: null, + eagerState: null, + next: null + }; + + { + update.priority = getCurrentPriorityLevel(); + } // Append the update to the end of the list. + + var pending = queue.pending; + + if (pending === null) { + // This is the first update. Create a circular list. + update.next = update; + } else { + update.next = pending.next; + pending.next = update; + } + + queue.pending = update; var alternate = fiber.alternate; if ( @@ -11609,70 +11709,9 @@ function dispatchAction(fiber, queue, action) { // queue -> linked list of updates. After this render pass, we'll restart // and apply the stashed updates on top of the work-in-progress hook. didScheduleRenderPhaseUpdate = true; - var update = { - expirationTime: renderExpirationTime$1, - suspenseConfig: null, - action: action, - eagerReducer: null, - eagerState: null, - next: null - }; - - { - update.priority = getCurrentPriorityLevel(); - } - - if (renderPhaseUpdates === null) { - renderPhaseUpdates = new Map(); - } - - var firstRenderPhaseUpdate = renderPhaseUpdates.get(queue); - - if (firstRenderPhaseUpdate === undefined) { - renderPhaseUpdates.set(queue, update); - } else { - // Append the update to the end of the list. - var lastRenderPhaseUpdate = firstRenderPhaseUpdate; - - while (lastRenderPhaseUpdate.next !== null) { - lastRenderPhaseUpdate = lastRenderPhaseUpdate.next; - } - - lastRenderPhaseUpdate.next = update; - } + update.expirationTime = renderExpirationTime$1; + currentlyRenderingFiber$1.expirationTime = renderExpirationTime$1; } else { - var currentTime = requestCurrentTimeForUpdate(); - var suspenseConfig = requestCurrentSuspenseConfig(); - var expirationTime = computeExpirationForFiber( - currentTime, - fiber, - suspenseConfig - ); - var _update2 = { - expirationTime: expirationTime, - suspenseConfig: suspenseConfig, - action: action, - eagerReducer: null, - eagerState: null, - next: null - }; - - { - _update2.priority = getCurrentPriorityLevel(); - } // Append the update to the end of the list. - - var pending = queue.pending; - - if (pending === null) { - // This is the first update. Create a circular list. - _update2.next = _update2; - } else { - _update2.next = pending.next; - pending.next = _update2; - } - - queue.pending = _update2; - if ( fiber.expirationTime === NoWork && (alternate === null || alternate.expirationTime === NoWork) @@ -11697,10 +11736,10 @@ function dispatchAction(fiber, queue, action) { // time we enter the render phase, then the eager state can be used // without calling the reducer again. - _update2.eagerReducer = lastRenderedReducer; - _update2.eagerState = eagerState; + update.eagerReducer = lastRenderedReducer; + update.eagerState = eagerState; - if (is$1(eagerState, currentState)) { + if (objectIs(eagerState, currentState)) { // Fast path. We can bail out without scheduling React to re-render. // It's still possible that we'll need to rebase this update later, // if the component re-renders for a different reason and by that @@ -11748,8 +11787,10 @@ var ContextOnlyDispatcher = { var HooksDispatcherOnMountInDEV = null; var HooksDispatcherOnMountWithHookTypesInDEV = null; var HooksDispatcherOnUpdateInDEV = null; +var HooksDispatcherOnRerenderInDEV = null; var InvalidNestedHooksDispatcherOnMountInDEV = null; var InvalidNestedHooksDispatcherOnUpdateInDEV = null; +var InvalidNestedHooksDispatcherOnRerenderInDEV = null; { var warnInvalidContextAccess = function() { @@ -12048,6 +12089,97 @@ var InvalidNestedHooksDispatcherOnUpdateInDEV = null; return updateTransition(config); } }; + HooksDispatcherOnRerenderInDEV = { + readContext: function(context, observedBits) { + return readContext(context, observedBits); + }, + useCallback: function(callback, deps) { + currentHookNameInDev = "useCallback"; + updateHookTypesDev(); + return updateCallback(callback, deps); + }, + useContext: function(context, observedBits) { + currentHookNameInDev = "useContext"; + updateHookTypesDev(); + return readContext(context, observedBits); + }, + useEffect: function(create, deps) { + currentHookNameInDev = "useEffect"; + updateHookTypesDev(); + return updateEffect(create, deps); + }, + useImperativeHandle: function(ref, create, deps) { + currentHookNameInDev = "useImperativeHandle"; + updateHookTypesDev(); + return updateImperativeHandle(ref, create, deps); + }, + useLayoutEffect: function(create, deps) { + currentHookNameInDev = "useLayoutEffect"; + updateHookTypesDev(); + return updateLayoutEffect(create, deps); + }, + useMemo: function(create, deps) { + currentHookNameInDev = "useMemo"; + updateHookTypesDev(); + var prevDispatcher = ReactCurrentDispatcher$1.current; + ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnRerenderInDEV; + + try { + return updateMemo(create, deps); + } finally { + ReactCurrentDispatcher$1.current = prevDispatcher; + } + }, + useReducer: function(reducer, initialArg, init) { + currentHookNameInDev = "useReducer"; + updateHookTypesDev(); + var prevDispatcher = ReactCurrentDispatcher$1.current; + ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnRerenderInDEV; + + try { + return rerenderReducer(reducer, initialArg, init); + } finally { + ReactCurrentDispatcher$1.current = prevDispatcher; + } + }, + useRef: function(initialValue) { + currentHookNameInDev = "useRef"; + updateHookTypesDev(); + return updateRef(initialValue); + }, + useState: function(initialState) { + currentHookNameInDev = "useState"; + updateHookTypesDev(); + var prevDispatcher = ReactCurrentDispatcher$1.current; + ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnRerenderInDEV; + + try { + return rerenderState(initialState); + } finally { + ReactCurrentDispatcher$1.current = prevDispatcher; + } + }, + useDebugValue: function(value, formatterFn) { + currentHookNameInDev = "useDebugValue"; + updateHookTypesDev(); + return updateDebugValue(value, formatterFn); + }, + useResponder: function(responder, props) { + currentHookNameInDev = "useResponder"; + updateHookTypesDev(); + return createDeprecatedResponderListener(responder, props); + }, + useDeferredValue: function(value, config) { + currentHookNameInDev = "useDeferredValue"; + updateHookTypesDev(); + return rerenderDeferredValue(value, config); + }, + useTransition: function(config) { + currentHookNameInDev = "useTransition"; + updateHookTypesDev(); + return rerenderTransition(config); + } + }; InvalidNestedHooksDispatcherOnMountInDEV = { readContext: function(context, observedBits) { warnInvalidContextAccess(); @@ -12258,6 +12390,111 @@ var InvalidNestedHooksDispatcherOnUpdateInDEV = null; return updateTransition(config); } }; + InvalidNestedHooksDispatcherOnRerenderInDEV = { + readContext: function(context, observedBits) { + warnInvalidContextAccess(); + return readContext(context, observedBits); + }, + useCallback: function(callback, deps) { + currentHookNameInDev = "useCallback"; + warnInvalidHookAccess(); + updateHookTypesDev(); + return updateCallback(callback, deps); + }, + useContext: function(context, observedBits) { + currentHookNameInDev = "useContext"; + warnInvalidHookAccess(); + updateHookTypesDev(); + return readContext(context, observedBits); + }, + useEffect: function(create, deps) { + currentHookNameInDev = "useEffect"; + warnInvalidHookAccess(); + updateHookTypesDev(); + return updateEffect(create, deps); + }, + useImperativeHandle: function(ref, create, deps) { + currentHookNameInDev = "useImperativeHandle"; + warnInvalidHookAccess(); + updateHookTypesDev(); + return updateImperativeHandle(ref, create, deps); + }, + useLayoutEffect: function(create, deps) { + currentHookNameInDev = "useLayoutEffect"; + warnInvalidHookAccess(); + updateHookTypesDev(); + return updateLayoutEffect(create, deps); + }, + useMemo: function(create, deps) { + currentHookNameInDev = "useMemo"; + warnInvalidHookAccess(); + updateHookTypesDev(); + var prevDispatcher = ReactCurrentDispatcher$1.current; + ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV; + + try { + return updateMemo(create, deps); + } finally { + ReactCurrentDispatcher$1.current = prevDispatcher; + } + }, + useReducer: function(reducer, initialArg, init) { + currentHookNameInDev = "useReducer"; + warnInvalidHookAccess(); + updateHookTypesDev(); + var prevDispatcher = ReactCurrentDispatcher$1.current; + ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV; + + try { + return rerenderReducer(reducer, initialArg, init); + } finally { + ReactCurrentDispatcher$1.current = prevDispatcher; + } + }, + useRef: function(initialValue) { + currentHookNameInDev = "useRef"; + warnInvalidHookAccess(); + updateHookTypesDev(); + return updateRef(initialValue); + }, + useState: function(initialState) { + currentHookNameInDev = "useState"; + warnInvalidHookAccess(); + updateHookTypesDev(); + var prevDispatcher = ReactCurrentDispatcher$1.current; + ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV; + + try { + return rerenderState(initialState); + } finally { + ReactCurrentDispatcher$1.current = prevDispatcher; + } + }, + useDebugValue: function(value, formatterFn) { + currentHookNameInDev = "useDebugValue"; + warnInvalidHookAccess(); + updateHookTypesDev(); + return updateDebugValue(value, formatterFn); + }, + useResponder: function(responder, props) { + currentHookNameInDev = "useResponder"; + warnInvalidHookAccess(); + updateHookTypesDev(); + return createDeprecatedResponderListener(responder, props); + }, + useDeferredValue: function(value, config) { + currentHookNameInDev = "useDeferredValue"; + warnInvalidHookAccess(); + updateHookTypesDev(); + return rerenderDeferredValue(value, config); + }, + useTransition: function(config) { + currentHookNameInDev = "useTransition"; + warnInvalidHookAccess(); + updateHookTypesDev(); + return rerenderTransition(config); + } + }; } // CommonJS interop named imports. @@ -13990,7 +14227,8 @@ function mountIndeterminateComponent( workInProgress.tag = ClassComponent; // Throw out any hooks that were used. - resetHooks(); // Push context providers early to prevent context stack mismatches. + workInProgress.memoizedState = null; + workInProgress.updateQueue = null; // Push context providers early to prevent context stack mismatches. // During mounting we don't know the child context yet as the instance doesn't exist. // We will invalidate the child context in finishClassComponent() right after rendering. @@ -16018,17 +16256,16 @@ var emptyObject$2 = {}; function collectScopedNodes(node, fn, scopedNodes) { if (enableScopeAPI) { if (node.tag === HostComponent) { - var _type = node.type, + var type = node.type, memoizedProps = node.memoizedProps, stateNode = node.stateNode; - - var _instance = getPublicInstance(stateNode); + var instance = getPublicInstance(stateNode); if ( - _instance !== null && - fn(_type, memoizedProps || emptyObject$2, _instance) === true + instance !== null && + fn(type, memoizedProps || emptyObject$2, instance) === true ) { - scopedNodes.push(_instance); + scopedNodes.push(instance); } } @@ -16047,17 +16284,13 @@ function collectScopedNodes(node, fn, scopedNodes) { function collectFirstScopedNode(node, fn) { if (enableScopeAPI) { if (node.tag === HostComponent) { - var _type2 = node.type, + var type = node.type, memoizedProps = node.memoizedProps, stateNode = node.stateNode; + var instance = getPublicInstance(stateNode); - var _instance2 = getPublicInstance(stateNode); - - if ( - _instance2 !== null && - fn(_type2, memoizedProps, _instance2) === true - ) { - return _instance2; + if (instance !== null && fn(type, memoizedProps, instance) === true) { + return instance; } } @@ -16100,9 +16333,10 @@ function collectFirstScopedNodeFromChildren(startingChild, fn) { return null; } -function collectNearestScopeMethods(node, scope, childrenScopes) { - if (isValidScopeNode(node, scope)) { - childrenScopes.push(node.stateNode.methods); +function collectNearestContextValues(node, context, childContextValues) { + if (node.tag === ContextProvider && node.type._context === context) { + var contextValue = node.memoizedProps.value; + childContextValues.push(contextValue); } else { var child = node.child; @@ -16111,81 +16345,27 @@ function collectNearestScopeMethods(node, scope, childrenScopes) { } if (child !== null) { - collectNearestChildScopeMethods(child, scope, childrenScopes); + collectNearestChildContextValues(child, context, childContextValues); } } } -function collectNearestChildScopeMethods(startingChild, scope, childrenScopes) { +function collectNearestChildContextValues( + startingChild, + context, + childContextValues +) { var child = startingChild; while (child !== null) { - collectNearestScopeMethods(child, scope, childrenScopes); + collectNearestContextValues(child, context, childContextValues); child = child.sibling; } } -function isValidScopeNode(node, scope) { - return ( - node.tag === ScopeComponent && - node.type === scope && - node.stateNode !== null - ); -} - function createScopeMethods(scope, instance) { return { - getChildren: function() { - var currentFiber = instance.fiber; - var child = currentFiber.child; - var childrenScopes = []; - - if (child !== null) { - collectNearestChildScopeMethods(child, scope, childrenScopes); - } - - return childrenScopes.length === 0 ? null : childrenScopes; - }, - getChildrenFromRoot: function() { - var currentFiber = instance.fiber; - var node = currentFiber; - - while (node !== null) { - var parent = node.return; - - if (parent === null) { - break; - } - - node = parent; - - if (node.tag === ScopeComponent && node.type === scope) { - break; - } - } - - var childrenScopes = []; - collectNearestChildScopeMethods(node.child, scope, childrenScopes); - return childrenScopes.length === 0 ? null : childrenScopes; - }, - getParent: function() { - var node = instance.fiber.return; - - while (node !== null) { - if (node.tag === ScopeComponent && node.type === scope) { - return node.stateNode.methods; - } - - node = node.return; - } - - return null; - }, - getProps: function() { - var currentFiber = instance.fiber; - return currentFiber.memoizedProps; - }, - queryAllNodes: function(fn) { + DO_NOT_USE_queryAllNodes: function(fn) { var currentFiber = instance.fiber; var child = currentFiber.child; var scopedNodes = []; @@ -16196,7 +16376,7 @@ function createScopeMethods(scope, instance) { return scopedNodes.length === 0 ? null : scopedNodes; }, - queryFirstNode: function(fn) { + DO_NOT_USE_queryFirstNode: function(fn) { var currentFiber = instance.fiber; var child = currentFiber.child; @@ -16222,6 +16402,17 @@ function createScopeMethods(scope, instance) { } return false; + }, + getChildContextValues: function(context) { + var currentFiber = instance.fiber; + var child = currentFiber.child; + var childContextValues = []; + + if (child !== null) { + collectNearestChildContextValues(child, context, childContextValues); + } + + return childContextValues; } }; } @@ -20619,7 +20810,7 @@ function handleError(root, thrownValue) { try { // Reset module-level state that was set during the render phase. resetContextDependencies(); - resetHooks(); + resetHooksAfterThrow(); resetCurrentFiber(); if (workInProgress === null || workInProgress.return === null) { @@ -21785,16 +21976,16 @@ function jnd(timeElapsed) { return timeElapsed < 120 ? 120 : timeElapsed < 480 - ? 480 - : timeElapsed < 1080 - ? 1080 - : timeElapsed < 1920 - ? 1920 - : timeElapsed < 3000 - ? 3000 - : timeElapsed < 4320 - ? 4320 - : ceil(timeElapsed / 1960) * 1960; + ? 480 + : timeElapsed < 1080 + ? 1080 + : timeElapsed < 1920 + ? 1920 + : timeElapsed < 3000 + ? 3000 + : timeElapsed < 4320 + ? 4320 + : ceil(timeElapsed / 1960) * 1960; } function computeMsUntilSuspenseLoadingDelay( @@ -21961,7 +22152,7 @@ if (true && replayFailedUnitOfWorkWithInvokeGuardedCallback) { // corresponding changes there. resetContextDependencies(); - resetHooks(); // Don't reset current debug fiber, since we're about to work on the + resetHooksAfterThrow(); // Don't reset current debug fiber, since we're about to work on the // same fiber again. // Unwind the failed stack frame @@ -23710,7 +23901,7 @@ function createPortal( // TODO: this is special because it gets imported during build. -var ReactVersion = "16.12.0-experimental-19f6fe170"; +var ReactVersion = "16.12.0-experimental-241c4467e"; var NativeMethodsMixin = function(findNodeHandle, findHostInstance) { /** diff --git a/Libraries/Renderer/implementations/ReactNativeRenderer-dev.js b/Libraries/Renderer/implementations/ReactNativeRenderer-dev.js index 991466c68d..58e10eb29e 100644 --- a/Libraries/Renderer/implementations/ReactNativeRenderer-dev.js +++ b/Libraries/Renderer/implementations/ReactNativeRenderer-dev.js @@ -688,14 +688,14 @@ var validateEventDispatches; var listenersLen = listenersIsArr ? dispatchListeners.length : dispatchListeners - ? 1 - : 0; + ? 1 + : 0; var instancesIsArr = Array.isArray(dispatchInstances); var instancesLen = instancesIsArr ? dispatchInstances.length : dispatchInstances - ? 1 - : 0; + ? 1 + : 0; if (instancesIsArr !== listenersIsArr || instancesLen !== listenersLen) { error("EventPluginUtils: Invalid `event`."); @@ -2263,10 +2263,10 @@ function setResponderAndExtractTransfer( var shouldSetEventType = isStartish(topLevelType) ? eventTypes.startShouldSetResponder : isMoveish(topLevelType) - ? eventTypes.moveShouldSetResponder - : topLevelType === TOP_SELECTION_CHANGE - ? eventTypes.selectionChangeShouldSetResponder - : eventTypes.scrollShouldSetResponder; // TODO: stop one short of the current responder. + ? eventTypes.moveShouldSetResponder + : topLevelType === TOP_SELECTION_CHANGE + ? eventTypes.selectionChangeShouldSetResponder + : eventTypes.scrollShouldSetResponder; // TODO: stop one short of the current responder. var bubbleShouldSetFrom = !responderInst ? targetInst @@ -2470,10 +2470,10 @@ var ResponderEventPlugin = { var incrementalTouch = isResponderTouchStart ? eventTypes.responderStart : isResponderTouchMove - ? eventTypes.responderMove - : isResponderTouchEnd - ? eventTypes.responderEnd - : null; + ? eventTypes.responderMove + : isResponderTouchEnd + ? eventTypes.responderEnd + : null; if (incrementalTouch) { var gesture = ResponderSyntheticEvent.getPooled( @@ -2497,8 +2497,8 @@ var ResponderEventPlugin = { var finalTouch = isResponderTerminate ? eventTypes.responderTerminate : isResponderRelease - ? eventTypes.responderRelease - : null; + ? eventTypes.responderRelease + : null; if (finalTouch) { var finalEvent = ResponderSyntheticEvent.getPooled( @@ -2628,9 +2628,11 @@ var warnAboutDefaultPropsOnFunctionComponents = false; var warnAboutStringRefs = false; var disableLegacyContext = false; var disableSchedulerTimeoutBasedOnReactExpirationTime = false; -var enableTrainModelFix = false; +var enableTrainModelFix = true; -var enableNativeTargetAsInstance = false; // Only used in www builds. +var enableNativeTargetAsInstance = false; + +// Only used in www builds. // Flow magic to verify the exports of this file match the original version. @@ -5852,7 +5854,7 @@ function is(x, y) { ); } -var is$1 = typeof Object.is === "function" ? Object.is : is; +var objectIs = typeof Object.is === "function" ? Object.is : is; var hasOwnProperty = Object.prototype.hasOwnProperty; /** @@ -5862,7 +5864,7 @@ var hasOwnProperty = Object.prototype.hasOwnProperty; */ function shallowEqual(objA, objB) { - if (is$1(objA, objB)) { + if (objectIs(objA, objB)) { return true; } @@ -5885,7 +5887,7 @@ function shallowEqual(objA, objB) { for (var i = 0; i < keysA.length; i++) { if ( !hasOwnProperty.call(objB, keysA[i]) || - !is$1(objA[keysA[i]], objB[keysA[i]]) + !objectIs(objA[keysA[i]], objB[keysA[i]]) ) { return false; } @@ -6202,13 +6204,18 @@ var ReactStrictModeWarnings = { ReactStrictModeWarnings.flushLegacyContextWarning = function() { pendingLegacyContextWarning.forEach(function(fiberArray, strictRoot) { + if (fiberArray.length === 0) { + return; + } + + var firstFiber = fiberArray[0]; var uniqueNames = new Set(); fiberArray.forEach(function(fiber) { uniqueNames.add(getComponentName(fiber.type) || "Component"); didWarnAboutLegacyContext.add(fiber.type); }); var sortedNames = setToSortedString(uniqueNames); - var strictRootComponentStack = getStackByFiberInDevAndProd(strictRoot); + var firstComponentStack = getStackByFiberInDevAndProd(firstFiber); error( "Legacy context API has been detected within a strict-mode tree." + @@ -6218,7 +6225,7 @@ var ReactStrictModeWarnings = { "\n\nLearn more about this warning here: https://fb.me/react-legacy-context" + "%s", sortedNames, - strictRootComponentStack + firstComponentStack ); }); }; @@ -6788,7 +6795,7 @@ function popProvider(providerFiber) { } } function calculateChangedBits(context, newValue, oldValue) { - if (is$1(oldValue, newValue)) { + if (objectIs(oldValue, newValue)) { // No change return 0; } else { @@ -8749,7 +8756,16 @@ function coerceRef(returnFiber, current$$1, element) { { // TODO: Clean this up once we turn on the string ref warning for // everyone, because the strict mode case will no longer be relevant - if (returnFiber.mode & StrictMode || warnAboutStringRefs) { + if ( + (returnFiber.mode & StrictMode || warnAboutStringRefs) && // We warn in ReactElement.js if owner and self are equal for string refs + // because these cannot be automatically converted to an arrow function + // using a codemod. Therefore, we don't have to warn about string refs again. + !( + element._owner && + element._self && + element._owner.stateNode !== element._self + ) + ) { var componentName = getComponentName(returnFiber.type) || "Component"; if (!didWarnAboutStringRefs[componentName]) { @@ -10611,20 +10627,12 @@ var currentlyRenderingFiber$1 = null; // Hooks are stored as a linked list on th // work-in-progress fiber. var currentHook = null; -var workInProgressHook = null; // Updates scheduled during render will trigger an immediate re-render at the -// end of the current pass. We can't store these updates on the normal queue, -// because if the work is aborted, they should be discarded. Because this is -// a relatively rare case, we also don't want to add an additional field to -// either the hook or queue object types. So we store them in a lazily create -// map of queue -> render-phase updates, which are discarded once the component -// completes without re-rendering. -// Whether an update was scheduled during the currently executing render pass. +var workInProgressHook = null; // Whether an update was scheduled at any point during the render phase. This +// does not get reset if we do another render pass; only when we're completely +// finished evaluating this component. This is an optimization so we know +// whether we need to clear render phase updates after a throw. -var didScheduleRenderPhaseUpdate = false; // Lazily created map of render-phase updates - -var renderPhaseUpdates = null; // Counter to prevent infinite loops. - -var numberOfReRenders = 0; +var didScheduleRenderPhaseUpdate = false; var RE_RENDER_LIMIT = 25; // In DEV, this is the name of the currently executing primitive hook var currentHookNameInDev = null; // In DEV, this list ensures that hooks are called in the same order between renders. @@ -10767,7 +10775,7 @@ function areHookInputsEqual(nextDeps, prevDeps) { } for (var i = 0; i < prevDeps.length && i < nextDeps.length; i++) { - if (is$1(nextDeps[i], prevDeps[i])) { + if (objectIs(nextDeps[i], prevDeps[i])) { continue; } @@ -10802,8 +10810,6 @@ function renderWithHooks( // currentHook = null; // workInProgressHook = null; // didScheduleRenderPhaseUpdate = false; - // renderPhaseUpdates = null; - // numberOfReRenders = 0; // TODO Warn if no hooks are used at all during mount, then some are used during update. // Currently we will identify the update render as a mount because memoizedState === null. // This is tricky because it's valid for certain types of components (e.g. React.lazy) @@ -10826,11 +10832,22 @@ function renderWithHooks( } } - var children = Component(props, secondArg); + var children = Component(props, secondArg); // Check if there was a render phase update + + if (workInProgress.expirationTime === renderExpirationTime$1) { + // Keep rendering in a loop for as long as render phase updates continue to + // be scheduled. Use a counter to prevent infinite loops. + var numberOfReRenders = 0; - if (didScheduleRenderPhaseUpdate) { do { - didScheduleRenderPhaseUpdate = false; + workInProgress.expirationTime = NoWork; + + if (!(numberOfReRenders < RE_RENDER_LIMIT)) { + throw Error( + "Too many re-renders. React limits the number of renders to prevent an infinite loop." + ); + } + numberOfReRenders += 1; { @@ -10848,12 +10865,9 @@ function renderWithHooks( hookTypesUpdateIndexDev = -1; } - ReactCurrentDispatcher$1.current = HooksDispatcherOnUpdateInDEV; + ReactCurrentDispatcher$1.current = HooksDispatcherOnRerenderInDEV; children = Component(props, secondArg); - } while (didScheduleRenderPhaseUpdate); - - renderPhaseUpdates = null; - numberOfReRenders = 0; + } while (workInProgress.expirationTime === renderExpirationTime$1); } // We can assume the previous dispatcher is always this one, since we set it // at the beginning of the render phase and there's no re-entrancy. @@ -10874,10 +10888,9 @@ function renderWithHooks( currentHookNameInDev = null; hookTypesDev = null; hookTypesUpdateIndexDev = -1; - } // These were reset above - // didScheduleRenderPhaseUpdate = false; - // renderPhaseUpdates = null; - // numberOfReRenders = 0; + } + + didScheduleRenderPhaseUpdate = false; if (!!didRenderTooFewHooks) { throw Error( @@ -10895,12 +10908,32 @@ function bailoutHooks(current, workInProgress, expirationTime) { current.expirationTime = NoWork; } } -function resetHooks() { +function resetHooksAfterThrow() { // We can assume the previous dispatcher is always this one, since we set it // at the beginning of the render phase and there's no re-entrancy. - ReactCurrentDispatcher$1.current = ContextOnlyDispatcher; // This is used to reset the state of this module when a component throws. - // It's also called inside mountIndeterminateComponent if we determine the - // component is a module-style component. + ReactCurrentDispatcher$1.current = ContextOnlyDispatcher; + + if (didScheduleRenderPhaseUpdate) { + // There were render phase updates. These are only valid for this render + // phase, which we are now aborting. Remove the updates from the queues so + // they do not persist to the next render. Do not remove updates from hooks + // that weren't processed. + // + // Only reset the updates from the queue if it has a clone. If it does + // not have a clone, that means it wasn't processed, and the updates were + // scheduled before we entered the render phase. + var hook = currentlyRenderingFiber$1.memoizedState; + + while (hook !== null) { + var queue = hook.queue; + + if (queue !== null) { + queue.pending = null; + } + + hook = hook.next; + } + } renderExpirationTime$1 = NoWork; currentlyRenderingFiber$1 = null; @@ -10914,8 +10947,6 @@ function resetHooks() { } didScheduleRenderPhaseUpdate = false; - renderPhaseUpdates = null; - numberOfReRenders = 0; } function mountWorkInProgressHook() { @@ -11005,6 +11036,7 @@ function createFunctionComponentUpdateQueue() { } function basicStateReducer(state, action) { + // $FlowFixMe: Flow doesn't like mixed types return typeof action === "function" ? action(state) : action; } @@ -11044,52 +11076,6 @@ function updateReducer(reducer, initialArg, init) { } queue.lastRenderedReducer = reducer; - - if (numberOfReRenders > 0) { - // This is a re-render. Apply the new render phase updates to the previous - // work-in-progress hook. - var _dispatch = queue.dispatch; - - if (renderPhaseUpdates !== null) { - // Render phase updates are stored in a map of queue -> linked list - var firstRenderPhaseUpdate = renderPhaseUpdates.get(queue); - - if (firstRenderPhaseUpdate !== undefined) { - renderPhaseUpdates.delete(queue); - var newState = hook.memoizedState; - var update = firstRenderPhaseUpdate; - - do { - // Process this render phase update. We don't have to check the - // priority because it will always be the same as the current - // render's. - var action = update.action; - newState = reducer(newState, action); - update = update.next; - } while (update !== null); // Mark that the fiber performed work, but only if the new state is - // different from the current state. - - if (!is$1(newState, hook.memoizedState)) { - markWorkInProgressReceivedUpdate(); - } - - hook.memoizedState = newState; // Don't persist the state accumulated from the render phase updates to - // the base state unless the queue is empty. - // TODO: Not sure if this is the desired semantics, but it's what we - // do for gDSFP. I can't remember why. - - if (hook.baseQueue === null) { - hook.baseState = newState; - } - - queue.lastRenderedState = newState; - return [newState, _dispatch]; - } - } - - return [hook.memoizedState, _dispatch]; - } - var current = currentHook; // The last rebase update that is NOT part of the base state. var baseQueue = current.baseQueue; // The last pending update that hasn't been processed yet. @@ -11114,31 +11100,31 @@ function updateReducer(reducer, initialArg, init) { if (baseQueue !== null) { // We have a queue to process. var first = baseQueue.next; - var _newState = current.baseState; + var newState = current.baseState; var newBaseState = null; var newBaseQueueFirst = null; var newBaseQueueLast = null; - var _update = first; + var update = first; do { - var updateExpirationTime = _update.expirationTime; + var updateExpirationTime = update.expirationTime; if (updateExpirationTime < renderExpirationTime$1) { // Priority is insufficient. Skip this update. If this is the first // skipped update, the previous update/state is the new base // update/state. var clone = { - expirationTime: _update.expirationTime, - suspenseConfig: _update.suspenseConfig, - action: _update.action, - eagerReducer: _update.eagerReducer, - eagerState: _update.eagerState, + expirationTime: update.expirationTime, + suspenseConfig: update.suspenseConfig, + action: update.action, + eagerReducer: update.eagerReducer, + eagerState: update.eagerState, next: null }; if (newBaseQueueLast === null) { newBaseQueueFirst = newBaseQueueLast = clone; - newBaseState = _newState; + newBaseState = newState; } else { newBaseQueueLast = newBaseQueueLast.next = clone; } // Update the remaining priority in the queue. @@ -11153,10 +11139,10 @@ function updateReducer(reducer, initialArg, init) { var _clone = { expirationTime: Sync, // This update is going to be committed so we never want uncommit it. - suspenseConfig: _update.suspenseConfig, - action: _update.action, - eagerReducer: _update.eagerReducer, - eagerState: _update.eagerState, + suspenseConfig: update.suspenseConfig, + action: update.action, + eagerReducer: update.eagerReducer, + eagerState: update.eagerState, next: null }; newBaseQueueLast = newBaseQueueLast.next = _clone; @@ -11169,47 +11155,100 @@ function updateReducer(reducer, initialArg, init) { markRenderEventTimeAndConfig( updateExpirationTime, - _update.suspenseConfig + update.suspenseConfig ); // Process this update. - if (_update.eagerReducer === reducer) { + if (update.eagerReducer === reducer) { // If this update was processed eagerly, and its reducer matches the // current reducer, we can use the eagerly computed state. - _newState = _update.eagerState; + newState = update.eagerState; } else { - var _action = _update.action; - _newState = reducer(_newState, _action); + var action = update.action; + newState = reducer(newState, action); } } - _update = _update.next; - } while (_update !== null && _update !== first); + update = update.next; + } while (update !== null && update !== first); if (newBaseQueueLast === null) { - newBaseState = _newState; + newBaseState = newState; } else { newBaseQueueLast.next = newBaseQueueFirst; } // Mark that the fiber performed work, but only if the new state is // different from the current state. - if (!is$1(_newState, hook.memoizedState)) { + if (!objectIs(newState, hook.memoizedState)) { markWorkInProgressReceivedUpdate(); } - hook.memoizedState = _newState; + hook.memoizedState = newState; hook.baseState = newBaseState; hook.baseQueue = newBaseQueueLast; - queue.lastRenderedState = _newState; + queue.lastRenderedState = newState; } var dispatch = queue.dispatch; return [hook.memoizedState, dispatch]; } +function rerenderReducer(reducer, initialArg, init) { + var hook = updateWorkInProgressHook(); + var queue = hook.queue; + + if (!(queue !== null)) { + throw Error( + "Should have a queue. This is likely a bug in React. Please file an issue." + ); + } + + queue.lastRenderedReducer = reducer; // This is a re-render. Apply the new render phase updates to the previous + // work-in-progress hook. + + var dispatch = queue.dispatch; + var lastRenderPhaseUpdate = queue.pending; + var newState = hook.memoizedState; + + if (lastRenderPhaseUpdate !== null) { + // The queue doesn't persist past this render pass. + queue.pending = null; + var firstRenderPhaseUpdate = lastRenderPhaseUpdate.next; + var update = firstRenderPhaseUpdate; + + do { + // Process this render phase update. We don't have to check the + // priority because it will always be the same as the current + // render's. + var action = update.action; + newState = reducer(newState, action); + update = update.next; + } while (update !== firstRenderPhaseUpdate); // Mark that the fiber performed work, but only if the new state is + // different from the current state. + + if (!objectIs(newState, hook.memoizedState)) { + markWorkInProgressReceivedUpdate(); + } + + hook.memoizedState = newState; // Don't persist the state accumulated from the render phase updates to + // the base state unless the queue is empty. + // TODO: Not sure if this is the desired semantics, but it's what we + // do for gDSFP. I can't remember why. + + if (hook.baseQueue === null) { + hook.baseState = newState; + } + + queue.lastRenderedState = newState; + } + + return [newState, dispatch]; +} + function mountState(initialState) { var hook = mountWorkInProgressHook(); if (typeof initialState === "function") { + // $FlowFixMe: Flow doesn't like mixed types initialState = initialState(); } @@ -11232,6 +11271,10 @@ function updateState(initialState) { return updateReducer(basicStateReducer, initialState); } +function rerenderState(initialState) { + return rerenderReducer(basicStateReducer, initialState); +} + function pushEffect(tag, create, destroy, deps) { var effect = { tag: tag, @@ -11531,6 +11574,27 @@ function updateDeferredValue(value, config) { return prevValue; } +function rerenderDeferredValue(value, config) { + var _rerenderState = rerenderState(value), + prevValue = _rerenderState[0], + setValue = _rerenderState[1]; + + updateEffect( + function() { + var previousConfig = ReactCurrentBatchConfig$1.suspense; + ReactCurrentBatchConfig$1.suspense = config === undefined ? null : config; + + try { + setValue(value); + } finally { + ReactCurrentBatchConfig$1.suspense = previousConfig; + } + }, + [value, config] + ); + return prevValue; +} + function startTransition(setPending, config, callback) { var priorityLevel = getCurrentPriorityLevel(); runWithPriority( @@ -11579,13 +11643,19 @@ function updateTransition(config) { return [start, isPending]; } -function dispatchAction(fiber, queue, action) { - if (!(numberOfReRenders < RE_RENDER_LIMIT)) { - throw Error( - "Too many re-renders. React limits the number of renders to prevent an infinite loop." - ); - } +function rerenderTransition(config) { + var _rerenderState2 = rerenderState(false), + isPending = _rerenderState2[0], + setPending = _rerenderState2[1]; + var start = updateCallback(startTransition.bind(null, setPending, config), [ + setPending, + config + ]); + return [start, isPending]; +} + +function dispatchAction(fiber, queue, action) { { if (typeof arguments[3] === "function") { error( @@ -11596,6 +11666,37 @@ function dispatchAction(fiber, queue, action) { } } + var currentTime = requestCurrentTimeForUpdate(); + var suspenseConfig = requestCurrentSuspenseConfig(); + var expirationTime = computeExpirationForFiber( + currentTime, + fiber, + suspenseConfig + ); + var update = { + expirationTime: expirationTime, + suspenseConfig: suspenseConfig, + action: action, + eagerReducer: null, + eagerState: null, + next: null + }; + + { + update.priority = getCurrentPriorityLevel(); + } // Append the update to the end of the list. + + var pending = queue.pending; + + if (pending === null) { + // This is the first update. Create a circular list. + update.next = update; + } else { + update.next = pending.next; + pending.next = update; + } + + queue.pending = update; var alternate = fiber.alternate; if ( @@ -11606,70 +11707,9 @@ function dispatchAction(fiber, queue, action) { // queue -> linked list of updates. After this render pass, we'll restart // and apply the stashed updates on top of the work-in-progress hook. didScheduleRenderPhaseUpdate = true; - var update = { - expirationTime: renderExpirationTime$1, - suspenseConfig: null, - action: action, - eagerReducer: null, - eagerState: null, - next: null - }; - - { - update.priority = getCurrentPriorityLevel(); - } - - if (renderPhaseUpdates === null) { - renderPhaseUpdates = new Map(); - } - - var firstRenderPhaseUpdate = renderPhaseUpdates.get(queue); - - if (firstRenderPhaseUpdate === undefined) { - renderPhaseUpdates.set(queue, update); - } else { - // Append the update to the end of the list. - var lastRenderPhaseUpdate = firstRenderPhaseUpdate; - - while (lastRenderPhaseUpdate.next !== null) { - lastRenderPhaseUpdate = lastRenderPhaseUpdate.next; - } - - lastRenderPhaseUpdate.next = update; - } + update.expirationTime = renderExpirationTime$1; + currentlyRenderingFiber$1.expirationTime = renderExpirationTime$1; } else { - var currentTime = requestCurrentTimeForUpdate(); - var suspenseConfig = requestCurrentSuspenseConfig(); - var expirationTime = computeExpirationForFiber( - currentTime, - fiber, - suspenseConfig - ); - var _update2 = { - expirationTime: expirationTime, - suspenseConfig: suspenseConfig, - action: action, - eagerReducer: null, - eagerState: null, - next: null - }; - - { - _update2.priority = getCurrentPriorityLevel(); - } // Append the update to the end of the list. - - var pending = queue.pending; - - if (pending === null) { - // This is the first update. Create a circular list. - _update2.next = _update2; - } else { - _update2.next = pending.next; - pending.next = _update2; - } - - queue.pending = _update2; - if ( fiber.expirationTime === NoWork && (alternate === null || alternate.expirationTime === NoWork) @@ -11694,10 +11734,10 @@ function dispatchAction(fiber, queue, action) { // time we enter the render phase, then the eager state can be used // without calling the reducer again. - _update2.eagerReducer = lastRenderedReducer; - _update2.eagerState = eagerState; + update.eagerReducer = lastRenderedReducer; + update.eagerState = eagerState; - if (is$1(eagerState, currentState)) { + if (objectIs(eagerState, currentState)) { // Fast path. We can bail out without scheduling React to re-render. // It's still possible that we'll need to rebase this update later, // if the component re-renders for a different reason and by that @@ -11745,8 +11785,10 @@ var ContextOnlyDispatcher = { var HooksDispatcherOnMountInDEV = null; var HooksDispatcherOnMountWithHookTypesInDEV = null; var HooksDispatcherOnUpdateInDEV = null; +var HooksDispatcherOnRerenderInDEV = null; var InvalidNestedHooksDispatcherOnMountInDEV = null; var InvalidNestedHooksDispatcherOnUpdateInDEV = null; +var InvalidNestedHooksDispatcherOnRerenderInDEV = null; { var warnInvalidContextAccess = function() { @@ -12045,6 +12087,97 @@ var InvalidNestedHooksDispatcherOnUpdateInDEV = null; return updateTransition(config); } }; + HooksDispatcherOnRerenderInDEV = { + readContext: function(context, observedBits) { + return readContext(context, observedBits); + }, + useCallback: function(callback, deps) { + currentHookNameInDev = "useCallback"; + updateHookTypesDev(); + return updateCallback(callback, deps); + }, + useContext: function(context, observedBits) { + currentHookNameInDev = "useContext"; + updateHookTypesDev(); + return readContext(context, observedBits); + }, + useEffect: function(create, deps) { + currentHookNameInDev = "useEffect"; + updateHookTypesDev(); + return updateEffect(create, deps); + }, + useImperativeHandle: function(ref, create, deps) { + currentHookNameInDev = "useImperativeHandle"; + updateHookTypesDev(); + return updateImperativeHandle(ref, create, deps); + }, + useLayoutEffect: function(create, deps) { + currentHookNameInDev = "useLayoutEffect"; + updateHookTypesDev(); + return updateLayoutEffect(create, deps); + }, + useMemo: function(create, deps) { + currentHookNameInDev = "useMemo"; + updateHookTypesDev(); + var prevDispatcher = ReactCurrentDispatcher$1.current; + ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnRerenderInDEV; + + try { + return updateMemo(create, deps); + } finally { + ReactCurrentDispatcher$1.current = prevDispatcher; + } + }, + useReducer: function(reducer, initialArg, init) { + currentHookNameInDev = "useReducer"; + updateHookTypesDev(); + var prevDispatcher = ReactCurrentDispatcher$1.current; + ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnRerenderInDEV; + + try { + return rerenderReducer(reducer, initialArg, init); + } finally { + ReactCurrentDispatcher$1.current = prevDispatcher; + } + }, + useRef: function(initialValue) { + currentHookNameInDev = "useRef"; + updateHookTypesDev(); + return updateRef(initialValue); + }, + useState: function(initialState) { + currentHookNameInDev = "useState"; + updateHookTypesDev(); + var prevDispatcher = ReactCurrentDispatcher$1.current; + ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnRerenderInDEV; + + try { + return rerenderState(initialState); + } finally { + ReactCurrentDispatcher$1.current = prevDispatcher; + } + }, + useDebugValue: function(value, formatterFn) { + currentHookNameInDev = "useDebugValue"; + updateHookTypesDev(); + return updateDebugValue(value, formatterFn); + }, + useResponder: function(responder, props) { + currentHookNameInDev = "useResponder"; + updateHookTypesDev(); + return createDeprecatedResponderListener(responder, props); + }, + useDeferredValue: function(value, config) { + currentHookNameInDev = "useDeferredValue"; + updateHookTypesDev(); + return rerenderDeferredValue(value, config); + }, + useTransition: function(config) { + currentHookNameInDev = "useTransition"; + updateHookTypesDev(); + return rerenderTransition(config); + } + }; InvalidNestedHooksDispatcherOnMountInDEV = { readContext: function(context, observedBits) { warnInvalidContextAccess(); @@ -12255,6 +12388,111 @@ var InvalidNestedHooksDispatcherOnUpdateInDEV = null; return updateTransition(config); } }; + InvalidNestedHooksDispatcherOnRerenderInDEV = { + readContext: function(context, observedBits) { + warnInvalidContextAccess(); + return readContext(context, observedBits); + }, + useCallback: function(callback, deps) { + currentHookNameInDev = "useCallback"; + warnInvalidHookAccess(); + updateHookTypesDev(); + return updateCallback(callback, deps); + }, + useContext: function(context, observedBits) { + currentHookNameInDev = "useContext"; + warnInvalidHookAccess(); + updateHookTypesDev(); + return readContext(context, observedBits); + }, + useEffect: function(create, deps) { + currentHookNameInDev = "useEffect"; + warnInvalidHookAccess(); + updateHookTypesDev(); + return updateEffect(create, deps); + }, + useImperativeHandle: function(ref, create, deps) { + currentHookNameInDev = "useImperativeHandle"; + warnInvalidHookAccess(); + updateHookTypesDev(); + return updateImperativeHandle(ref, create, deps); + }, + useLayoutEffect: function(create, deps) { + currentHookNameInDev = "useLayoutEffect"; + warnInvalidHookAccess(); + updateHookTypesDev(); + return updateLayoutEffect(create, deps); + }, + useMemo: function(create, deps) { + currentHookNameInDev = "useMemo"; + warnInvalidHookAccess(); + updateHookTypesDev(); + var prevDispatcher = ReactCurrentDispatcher$1.current; + ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV; + + try { + return updateMemo(create, deps); + } finally { + ReactCurrentDispatcher$1.current = prevDispatcher; + } + }, + useReducer: function(reducer, initialArg, init) { + currentHookNameInDev = "useReducer"; + warnInvalidHookAccess(); + updateHookTypesDev(); + var prevDispatcher = ReactCurrentDispatcher$1.current; + ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV; + + try { + return rerenderReducer(reducer, initialArg, init); + } finally { + ReactCurrentDispatcher$1.current = prevDispatcher; + } + }, + useRef: function(initialValue) { + currentHookNameInDev = "useRef"; + warnInvalidHookAccess(); + updateHookTypesDev(); + return updateRef(initialValue); + }, + useState: function(initialState) { + currentHookNameInDev = "useState"; + warnInvalidHookAccess(); + updateHookTypesDev(); + var prevDispatcher = ReactCurrentDispatcher$1.current; + ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV; + + try { + return rerenderState(initialState); + } finally { + ReactCurrentDispatcher$1.current = prevDispatcher; + } + }, + useDebugValue: function(value, formatterFn) { + currentHookNameInDev = "useDebugValue"; + warnInvalidHookAccess(); + updateHookTypesDev(); + return updateDebugValue(value, formatterFn); + }, + useResponder: function(responder, props) { + currentHookNameInDev = "useResponder"; + warnInvalidHookAccess(); + updateHookTypesDev(); + return createDeprecatedResponderListener(responder, props); + }, + useDeferredValue: function(value, config) { + currentHookNameInDev = "useDeferredValue"; + warnInvalidHookAccess(); + updateHookTypesDev(); + return rerenderDeferredValue(value, config); + }, + useTransition: function(config) { + currentHookNameInDev = "useTransition"; + warnInvalidHookAccess(); + updateHookTypesDev(); + return rerenderTransition(config); + } + }; } // CommonJS interop named imports. @@ -13987,7 +14225,8 @@ function mountIndeterminateComponent( workInProgress.tag = ClassComponent; // Throw out any hooks that were used. - resetHooks(); // Push context providers early to prevent context stack mismatches. + workInProgress.memoizedState = null; + workInProgress.updateQueue = null; // Push context providers early to prevent context stack mismatches. // During mounting we don't know the child context yet as the instance doesn't exist. // We will invalidate the child context in finishClassComponent() right after rendering. @@ -16015,17 +16254,16 @@ var emptyObject$2 = {}; function collectScopedNodes(node, fn, scopedNodes) { if (enableScopeAPI) { if (node.tag === HostComponent) { - var _type = node.type, + var type = node.type, memoizedProps = node.memoizedProps, stateNode = node.stateNode; - - var _instance = getPublicInstance(stateNode); + var instance = getPublicInstance(stateNode); if ( - _instance !== null && - fn(_type, memoizedProps || emptyObject$2, _instance) === true + instance !== null && + fn(type, memoizedProps || emptyObject$2, instance) === true ) { - scopedNodes.push(_instance); + scopedNodes.push(instance); } } @@ -16044,17 +16282,13 @@ function collectScopedNodes(node, fn, scopedNodes) { function collectFirstScopedNode(node, fn) { if (enableScopeAPI) { if (node.tag === HostComponent) { - var _type2 = node.type, + var type = node.type, memoizedProps = node.memoizedProps, stateNode = node.stateNode; + var instance = getPublicInstance(stateNode); - var _instance2 = getPublicInstance(stateNode); - - if ( - _instance2 !== null && - fn(_type2, memoizedProps, _instance2) === true - ) { - return _instance2; + if (instance !== null && fn(type, memoizedProps, instance) === true) { + return instance; } } @@ -16097,9 +16331,10 @@ function collectFirstScopedNodeFromChildren(startingChild, fn) { return null; } -function collectNearestScopeMethods(node, scope, childrenScopes) { - if (isValidScopeNode(node, scope)) { - childrenScopes.push(node.stateNode.methods); +function collectNearestContextValues(node, context, childContextValues) { + if (node.tag === ContextProvider && node.type._context === context) { + var contextValue = node.memoizedProps.value; + childContextValues.push(contextValue); } else { var child = node.child; @@ -16108,81 +16343,27 @@ function collectNearestScopeMethods(node, scope, childrenScopes) { } if (child !== null) { - collectNearestChildScopeMethods(child, scope, childrenScopes); + collectNearestChildContextValues(child, context, childContextValues); } } } -function collectNearestChildScopeMethods(startingChild, scope, childrenScopes) { +function collectNearestChildContextValues( + startingChild, + context, + childContextValues +) { var child = startingChild; while (child !== null) { - collectNearestScopeMethods(child, scope, childrenScopes); + collectNearestContextValues(child, context, childContextValues); child = child.sibling; } } -function isValidScopeNode(node, scope) { - return ( - node.tag === ScopeComponent && - node.type === scope && - node.stateNode !== null - ); -} - function createScopeMethods(scope, instance) { return { - getChildren: function() { - var currentFiber = instance.fiber; - var child = currentFiber.child; - var childrenScopes = []; - - if (child !== null) { - collectNearestChildScopeMethods(child, scope, childrenScopes); - } - - return childrenScopes.length === 0 ? null : childrenScopes; - }, - getChildrenFromRoot: function() { - var currentFiber = instance.fiber; - var node = currentFiber; - - while (node !== null) { - var parent = node.return; - - if (parent === null) { - break; - } - - node = parent; - - if (node.tag === ScopeComponent && node.type === scope) { - break; - } - } - - var childrenScopes = []; - collectNearestChildScopeMethods(node.child, scope, childrenScopes); - return childrenScopes.length === 0 ? null : childrenScopes; - }, - getParent: function() { - var node = instance.fiber.return; - - while (node !== null) { - if (node.tag === ScopeComponent && node.type === scope) { - return node.stateNode.methods; - } - - node = node.return; - } - - return null; - }, - getProps: function() { - var currentFiber = instance.fiber; - return currentFiber.memoizedProps; - }, - queryAllNodes: function(fn) { + DO_NOT_USE_queryAllNodes: function(fn) { var currentFiber = instance.fiber; var child = currentFiber.child; var scopedNodes = []; @@ -16193,7 +16374,7 @@ function createScopeMethods(scope, instance) { return scopedNodes.length === 0 ? null : scopedNodes; }, - queryFirstNode: function(fn) { + DO_NOT_USE_queryFirstNode: function(fn) { var currentFiber = instance.fiber; var child = currentFiber.child; @@ -16219,6 +16400,17 @@ function createScopeMethods(scope, instance) { } return false; + }, + getChildContextValues: function(context) { + var currentFiber = instance.fiber; + var child = currentFiber.child; + var childContextValues = []; + + if (child !== null) { + collectNearestChildContextValues(child, context, childContextValues); + } + + return childContextValues; } }; } @@ -20616,7 +20808,7 @@ function handleError(root, thrownValue) { try { // Reset module-level state that was set during the render phase. resetContextDependencies(); - resetHooks(); + resetHooksAfterThrow(); resetCurrentFiber(); if (workInProgress === null || workInProgress.return === null) { @@ -21782,16 +21974,16 @@ function jnd(timeElapsed) { return timeElapsed < 120 ? 120 : timeElapsed < 480 - ? 480 - : timeElapsed < 1080 - ? 1080 - : timeElapsed < 1920 - ? 1920 - : timeElapsed < 3000 - ? 3000 - : timeElapsed < 4320 - ? 4320 - : ceil(timeElapsed / 1960) * 1960; + ? 480 + : timeElapsed < 1080 + ? 1080 + : timeElapsed < 1920 + ? 1920 + : timeElapsed < 3000 + ? 3000 + : timeElapsed < 4320 + ? 4320 + : ceil(timeElapsed / 1960) * 1960; } function computeMsUntilSuspenseLoadingDelay( @@ -21958,7 +22150,7 @@ if (true && replayFailedUnitOfWorkWithInvokeGuardedCallback) { // corresponding changes there. resetContextDependencies(); - resetHooks(); // Don't reset current debug fiber, since we're about to work on the + resetHooksAfterThrow(); // Don't reset current debug fiber, since we're about to work on the // same fiber again. // Unwind the failed stack frame @@ -23707,7 +23899,7 @@ function createPortal( // TODO: this is special because it gets imported during build. -var ReactVersion = "16.12.0-19f6fe170"; +var ReactVersion = "16.12.0-241c4467e"; var NativeMethodsMixin = function(findNodeHandle, findHostInstance) { /** diff --git a/Libraries/Renderer/implementations/ReactNativeRenderer-prod.fb.js b/Libraries/Renderer/implementations/ReactNativeRenderer-prod.fb.js index 8f8de75dd0..cd711a4501 100644 --- a/Libraries/Renderer/implementations/ReactNativeRenderer-prod.fb.js +++ b/Libraries/Renderer/implementations/ReactNativeRenderer-prod.fb.js @@ -348,8 +348,8 @@ function SyntheticEvent( ((targetInst = dispatchConfig[propName]) ? (this[propName] = targetInst(nativeEvent)) : "target" === propName - ? (this.target = nativeEventTarget) - : (this[propName] = nativeEvent[propName])); + ? (this.target = nativeEventTarget) + : (this[propName] = nativeEvent[propName])); this.isDefaultPrevented = (null != nativeEvent.defaultPrevented ? nativeEvent.defaultPrevented : !1 === nativeEvent.returnValue) @@ -562,10 +562,10 @@ function accumulate(current, next) { return null == current ? next : Array.isArray(current) - ? current.concat(next) - : Array.isArray(next) - ? [current].concat(next) - : [current, next]; + ? current.concat(next) + : Array.isArray(next) + ? [current].concat(next) + : [current, next]; } var responderInst = null, trackedTouchCount = 0; @@ -667,10 +667,10 @@ var eventTypes = { var shouldSetEventType = isStartish(topLevelType) ? eventTypes.startShouldSetResponder : isMoveish(topLevelType) - ? eventTypes.moveShouldSetResponder - : "topSelectionChange" === topLevelType - ? eventTypes.selectionChangeShouldSetResponder - : eventTypes.scrollShouldSetResponder; + ? eventTypes.moveShouldSetResponder + : "topSelectionChange" === topLevelType + ? eventTypes.selectionChangeShouldSetResponder + : eventTypes.scrollShouldSetResponder; if (responderInst) b: { var JSCompiler_temp = responderInst; @@ -824,10 +824,10 @@ var eventTypes = { (shouldSetEventType = shouldSetEventType ? eventTypes.responderStart : JSCompiler_temp - ? eventTypes.responderMove - : targetInst - ? eventTypes.responderEnd - : null) + ? eventTypes.responderMove + : targetInst + ? eventTypes.responderEnd + : null) ) (shouldSetEventType = ResponderSyntheticEvent.getPooled( shouldSetEventType, @@ -890,8 +890,8 @@ var eventTypes = { (topLevelType = shouldSetEventType ? eventTypes.responderTerminate : topLevelType - ? eventTypes.responderRelease - : null) + ? eventTypes.responderRelease + : null) ) (nativeEvent = ResponderSyntheticEvent.getPooled( topLevelType, @@ -1375,8 +1375,8 @@ function diffNestedProperty( return nextProp ? addNestedProperty(updatePayload, nextProp, validAttributes) : prevProp - ? clearNestedProperty(updatePayload, prevProp, validAttributes) - : updatePayload; + ? clearNestedProperty(updatePayload, prevProp, validAttributes) + : updatePayload; if (!Array.isArray(prevProp) && !Array.isArray(nextProp)) return diffProperties(updatePayload, prevProp, nextProp, validAttributes); if (Array.isArray(prevProp) && Array.isArray(nextProp)) { @@ -1887,10 +1887,10 @@ function flushSyncCallbackQueueImpl() { function is(x, y) { return (x === y && (0 !== x || 1 / x === 1 / y)) || (x !== x && y !== y); } -var is$1 = "function" === typeof Object.is ? Object.is : is, +var objectIs = "function" === typeof Object.is ? Object.is : is, hasOwnProperty = Object.prototype.hasOwnProperty; function shallowEqual(objA, objB) { - if (is$1(objA, objB)) return !0; + if (objectIs(objA, objB)) return !0; if ( "object" !== typeof objA || null === objA || @@ -1904,7 +1904,7 @@ function shallowEqual(objA, objB) { for (keysB = 0; keysB < keysA.length; keysB++) if ( !hasOwnProperty.call(objB, keysA[keysB]) || - !is$1(objA[keysA[keysB]], objB[keysA[keysB]]) + !objectIs(objA[keysA[keysB]], objB[keysA[keysB]]) ) return !1; return !0; @@ -2256,8 +2256,8 @@ function checkShouldComponentUpdate( return "function" === typeof workInProgress.shouldComponentUpdate ? workInProgress.shouldComponentUpdate(newProps, newState, nextContext) : ctor.prototype && ctor.prototype.isPureReactComponent - ? !shallowEqual(oldProps, newProps) || !shallowEqual(oldState, newState) - : !0; + ? !shallowEqual(oldProps, newProps) || !shallowEqual(oldState, newState) + : !0; } function constructClassInstance(workInProgress, ctor, props) { var isLegacyContextConsumer = !1, @@ -3152,9 +3152,7 @@ var ReactCurrentDispatcher$1 = ReactSharedInternals.ReactCurrentDispatcher, currentlyRenderingFiber$1 = null, currentHook = null, workInProgressHook = null, - didScheduleRenderPhaseUpdate = !1, - renderPhaseUpdates = null, - numberOfReRenders = 0; + didScheduleRenderPhaseUpdate = !1; function throwInvalidHookError() { throw Error( "Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons:\n1. You might have mismatching versions of React and the renderer (such as React DOM)\n2. You might be breaking the Rules of Hooks\n3. You might have more than one copy of React in the same app\nSee https://fb.me/react-invalid-hook-call for tips about how to debug and fix this problem." @@ -3163,7 +3161,7 @@ function throwInvalidHookError() { function areHookInputsEqual(nextDeps, prevDeps) { if (null === prevDeps) return !1; for (var i = 0; i < prevDeps.length && i < nextDeps.length; i++) - if (!is$1(nextDeps[i], prevDeps[i])) return !1; + if (!objectIs(nextDeps[i], prevDeps[i])) return !1; return !0; } function renderWithHooks( @@ -3184,36 +3182,32 @@ function renderWithHooks( ? HooksDispatcherOnMount : HooksDispatcherOnUpdate; current = Component(props, secondArg); - if (didScheduleRenderPhaseUpdate) { - do - (didScheduleRenderPhaseUpdate = !1), - (numberOfReRenders += 1), - (workInProgressHook = currentHook = null), - (workInProgress.updateQueue = null), - (ReactCurrentDispatcher$1.current = HooksDispatcherOnUpdate), - (current = Component(props, secondArg)); - while (didScheduleRenderPhaseUpdate); - renderPhaseUpdates = null; - numberOfReRenders = 0; + if (workInProgress.expirationTime === renderExpirationTime$1) { + nextRenderExpirationTime = 0; + do { + workInProgress.expirationTime = 0; + if (!(25 > nextRenderExpirationTime)) + throw Error( + "Too many re-renders. React limits the number of renders to prevent an infinite loop." + ); + nextRenderExpirationTime += 1; + workInProgressHook = currentHook = null; + workInProgress.updateQueue = null; + ReactCurrentDispatcher$1.current = HooksDispatcherOnRerender; + current = Component(props, secondArg); + } while (workInProgress.expirationTime === renderExpirationTime$1); } ReactCurrentDispatcher$1.current = ContextOnlyDispatcher; workInProgress = null !== currentHook && null !== currentHook.next; renderExpirationTime$1 = 0; workInProgressHook = currentHook = currentlyRenderingFiber$1 = null; + didScheduleRenderPhaseUpdate = !1; if (workInProgress) throw Error( "Rendered fewer hooks than expected. This may be caused by an accidental early return statement." ); return current; } -function resetHooks() { - ReactCurrentDispatcher$1.current = ContextOnlyDispatcher; - renderExpirationTime$1 = 0; - workInProgressHook = currentHook = currentlyRenderingFiber$1 = null; - didScheduleRenderPhaseUpdate = !1; - renderPhaseUpdates = null; - numberOfReRenders = 0; -} function mountWorkInProgressHook() { var hook = { memoizedState: null, @@ -3268,57 +3262,36 @@ function updateReducer(reducer) { "Should have a queue. This is likely a bug in React. Please file an issue." ); queue.lastRenderedReducer = reducer; - if (0 < numberOfReRenders) { - var _dispatch = queue.dispatch; - if (null !== renderPhaseUpdates) { - var firstRenderPhaseUpdate = renderPhaseUpdates.get(queue); - if (void 0 !== firstRenderPhaseUpdate) { - renderPhaseUpdates.delete(queue); - var newState = hook.memoizedState; - do - (newState = reducer(newState, firstRenderPhaseUpdate.action)), - (firstRenderPhaseUpdate = firstRenderPhaseUpdate.next); - while (null !== firstRenderPhaseUpdate); - is$1(newState, hook.memoizedState) || (didReceiveUpdate = !0); - hook.memoizedState = newState; - null === hook.baseQueue && (hook.baseState = newState); - queue.lastRenderedState = newState; - return [newState, _dispatch]; - } + var current = currentHook, + baseQueue = current.baseQueue, + pendingQueue = queue.pending; + if (null !== pendingQueue) { + if (null !== baseQueue) { + var baseFirst = baseQueue.next; + baseQueue.next = pendingQueue.next; + pendingQueue.next = baseFirst; } - return [hook.memoizedState, _dispatch]; - } - newState = currentHook; - _dispatch = newState.baseQueue; - firstRenderPhaseUpdate = queue.pending; - if (null !== firstRenderPhaseUpdate) { - if (null !== _dispatch) { - var baseFirst = _dispatch.next; - _dispatch.next = firstRenderPhaseUpdate.next; - firstRenderPhaseUpdate.next = baseFirst; - } - newState.baseQueue = _dispatch = firstRenderPhaseUpdate; + current.baseQueue = baseQueue = pendingQueue; queue.pending = null; } - if (null !== _dispatch) { - _dispatch = _dispatch.next; - newState = newState.baseState; - var newBaseQueueLast = (baseFirst = firstRenderPhaseUpdate = null), - _update = _dispatch; + if (null !== baseQueue) { + baseQueue = baseQueue.next; + current = current.baseState; + var newBaseQueueLast = (baseFirst = pendingQueue = null), + update = baseQueue; do { - var updateExpirationTime = _update.expirationTime; + var updateExpirationTime = update.expirationTime; if (updateExpirationTime < renderExpirationTime$1) { var clone = { - expirationTime: _update.expirationTime, - suspenseConfig: _update.suspenseConfig, - action: _update.action, - eagerReducer: _update.eagerReducer, - eagerState: _update.eagerState, + expirationTime: update.expirationTime, + suspenseConfig: update.suspenseConfig, + action: update.action, + eagerReducer: update.eagerReducer, + eagerState: update.eagerState, next: null }; null === newBaseQueueLast - ? ((baseFirst = newBaseQueueLast = clone), - (firstRenderPhaseUpdate = newState)) + ? ((baseFirst = newBaseQueueLast = clone), (pendingQueue = current)) : (newBaseQueueLast = newBaseQueueLast.next = clone); updateExpirationTime > currentlyRenderingFiber$1.expirationTime && ((currentlyRenderingFiber$1.expirationTime = updateExpirationTime), @@ -3327,33 +3300,56 @@ function updateReducer(reducer) { null !== newBaseQueueLast && (newBaseQueueLast = newBaseQueueLast.next = { expirationTime: 1073741823, - suspenseConfig: _update.suspenseConfig, - action: _update.action, - eagerReducer: _update.eagerReducer, - eagerState: _update.eagerState, + suspenseConfig: update.suspenseConfig, + action: update.action, + eagerReducer: update.eagerReducer, + eagerState: update.eagerState, next: null }), markRenderEventTimeAndConfig( updateExpirationTime, - _update.suspenseConfig + update.suspenseConfig ), - (newState = - _update.eagerReducer === reducer - ? _update.eagerState - : reducer(newState, _update.action)); - _update = _update.next; - } while (null !== _update && _update !== _dispatch); + (current = + update.eagerReducer === reducer + ? update.eagerState + : reducer(current, update.action)); + update = update.next; + } while (null !== update && update !== baseQueue); null === newBaseQueueLast - ? (firstRenderPhaseUpdate = newState) + ? (pendingQueue = current) : (newBaseQueueLast.next = baseFirst); - is$1(newState, hook.memoizedState) || (didReceiveUpdate = !0); - hook.memoizedState = newState; - hook.baseState = firstRenderPhaseUpdate; + objectIs(current, hook.memoizedState) || (didReceiveUpdate = !0); + hook.memoizedState = current; + hook.baseState = pendingQueue; hook.baseQueue = newBaseQueueLast; - queue.lastRenderedState = newState; + queue.lastRenderedState = current; } return [hook.memoizedState, queue.dispatch]; } +function rerenderReducer(reducer) { + var hook = updateWorkInProgressHook(), + queue = hook.queue; + if (null === queue) + throw Error( + "Should have a queue. This is likely a bug in React. Please file an issue." + ); + queue.lastRenderedReducer = reducer; + var dispatch = queue.dispatch, + lastRenderPhaseUpdate = queue.pending, + newState = hook.memoizedState; + if (null !== lastRenderPhaseUpdate) { + queue.pending = null; + var update = (lastRenderPhaseUpdate = lastRenderPhaseUpdate.next); + do (newState = reducer(newState, update.action)), (update = update.next); + while (update !== lastRenderPhaseUpdate); + objectIs(newState, hook.memoizedState) || (didReceiveUpdate = !0); + hook.memoizedState = newState; + null === hook.baseQueue && (hook.baseState = newState); + queue.lastRenderedState = newState; + } + return [newState, dispatch]; +} function mountState(initialState) { var hook = mountWorkInProgressHook(); "function" === typeof initialState && (initialState = initialState()); @@ -3374,6 +3370,9 @@ function mountState(initialState) { function updateState(initialState) { return updateReducer(basicStateReducer, initialState); } +function rerenderState(initialState) { + return rerenderReducer(basicStateReducer, initialState); +} function pushEffect(tag, create, destroy, deps) { tag = { tag: tag, create: create, destroy: destroy, deps: deps, next: null }; create = currentlyRenderingFiber$1.updateQueue; @@ -3390,6 +3389,9 @@ function pushEffect(tag, create, destroy, deps) { (create.lastEffect = tag))); return tag; } +function updateRef() { + return updateWorkInProgressHook().memoizedState; +} function mountEffectImpl(fiberEffectTag, hookEffectTag, create, deps) { var hook = mountWorkInProgressHook(); currentlyRenderingFiber$1.effectTag |= fiberEffectTag; @@ -3421,6 +3423,9 @@ function mountEffect(create, deps) { function updateEffect(create, deps) { return updateEffectImpl(516, 192, create, deps); } +function updateLayoutEffect(create, deps) { + return updateEffectImpl(4, 36, create, deps); +} function imperativeHandleEffect(create, ref) { if ("function" === typeof ref) return ( @@ -3439,6 +3444,15 @@ function imperativeHandleEffect(create, ref) { } ); } +function updateImperativeHandle(ref, create, deps) { + deps = null !== deps && void 0 !== deps ? deps.concat([ref]) : null; + return updateEffectImpl( + 4, + 36, + imperativeHandleEffect.bind(null, create, ref), + deps + ); +} function mountDebugValue() {} function mountCallback(callback, deps) { mountWorkInProgressHook().memoizedState = [ @@ -3460,6 +3474,20 @@ function updateCallback(callback, deps) { hook.memoizedState = [callback, deps]; return callback; } +function updateMemo(nextCreate, deps) { + var hook = updateWorkInProgressHook(); + deps = void 0 === deps ? null : deps; + var prevState = hook.memoizedState; + if ( + null !== prevState && + null !== deps && + areHookInputsEqual(deps, prevState[1]) + ) + return prevState[0]; + nextCreate = nextCreate(); + hook.memoizedState = [nextCreate, deps]; + return nextCreate; +} function startTransition(setPending, config, callback) { var priorityLevel = getCurrentPriorityLevel(); runWithPriority(98 > priorityLevel ? 98 : priorityLevel, function() { @@ -3476,62 +3504,42 @@ function startTransition(setPending, config, callback) { }); } function dispatchAction(fiber, queue, action) { - if (!(25 > numberOfReRenders)) - throw Error( - "Too many re-renders. React limits the number of renders to prevent an infinite loop." - ); - var alternate = fiber.alternate; + var currentTime = requestCurrentTimeForUpdate(), + suspenseConfig = ReactCurrentBatchConfig.suspense; + currentTime = computeExpirationForFiber(currentTime, fiber, suspenseConfig); + suspenseConfig = { + expirationTime: currentTime, + suspenseConfig: suspenseConfig, + action: action, + eagerReducer: null, + eagerState: null, + next: null + }; + var pending = queue.pending; + null === pending + ? (suspenseConfig.next = suspenseConfig) + : ((suspenseConfig.next = pending.next), (pending.next = suspenseConfig)); + queue.pending = suspenseConfig; + pending = fiber.alternate; if ( fiber === currentlyRenderingFiber$1 || - (null !== alternate && alternate === currentlyRenderingFiber$1) + (null !== pending && pending === currentlyRenderingFiber$1) ) - if ( - ((didScheduleRenderPhaseUpdate = !0), - (fiber = { - expirationTime: renderExpirationTime$1, - suspenseConfig: null, - action: action, - eagerReducer: null, - eagerState: null, - next: null - }), - null === renderPhaseUpdates && (renderPhaseUpdates = new Map()), - (action = renderPhaseUpdates.get(queue)), - void 0 === action) - ) - renderPhaseUpdates.set(queue, fiber); - else { - for (queue = action; null !== queue.next; ) queue = queue.next; - queue.next = fiber; - } + (didScheduleRenderPhaseUpdate = !0), + (suspenseConfig.expirationTime = renderExpirationTime$1), + (currentlyRenderingFiber$1.expirationTime = renderExpirationTime$1); else { - var currentTime = requestCurrentTimeForUpdate(), - suspenseConfig = ReactCurrentBatchConfig.suspense; - currentTime = computeExpirationForFiber(currentTime, fiber, suspenseConfig); - suspenseConfig = { - expirationTime: currentTime, - suspenseConfig: suspenseConfig, - action: action, - eagerReducer: null, - eagerState: null, - next: null - }; - var pending = queue.pending; - null === pending - ? (suspenseConfig.next = suspenseConfig) - : ((suspenseConfig.next = pending.next), (pending.next = suspenseConfig)); - queue.pending = suspenseConfig; if ( 0 === fiber.expirationTime && - (null === alternate || 0 === alternate.expirationTime) && - ((alternate = queue.lastRenderedReducer), null !== alternate) + (null === pending || 0 === pending.expirationTime) && + ((pending = queue.lastRenderedReducer), null !== pending) ) try { var currentState = queue.lastRenderedState, - eagerState = alternate(currentState, action); - suspenseConfig.eagerReducer = alternate; + eagerState = pending(currentState, action); + suspenseConfig.eagerReducer = pending; suspenseConfig.eagerState = eagerState; - if (is$1(eagerState, currentState)) return; + if (objectIs(eagerState, currentState)) return; } catch (error) { } finally { } @@ -3640,36 +3648,11 @@ var ContextOnlyDispatcher = { useCallback: updateCallback, useContext: readContext, useEffect: updateEffect, - useImperativeHandle: function(ref, create, deps) { - deps = null !== deps && void 0 !== deps ? deps.concat([ref]) : null; - return updateEffectImpl( - 4, - 36, - imperativeHandleEffect.bind(null, create, ref), - deps - ); - }, - useLayoutEffect: function(create, deps) { - return updateEffectImpl(4, 36, create, deps); - }, - useMemo: function(nextCreate, deps) { - var hook = updateWorkInProgressHook(); - deps = void 0 === deps ? null : deps; - var prevState = hook.memoizedState; - if ( - null !== prevState && - null !== deps && - areHookInputsEqual(deps, prevState[1]) - ) - return prevState[0]; - nextCreate = nextCreate(); - hook.memoizedState = [nextCreate, deps]; - return nextCreate; - }, + useImperativeHandle: updateImperativeHandle, + useLayoutEffect: updateLayoutEffect, + useMemo: updateMemo, useReducer: updateReducer, - useRef: function() { - return updateWorkInProgressHook().memoizedState; - }, + useRef: updateRef, useState: updateState, useDebugValue: mountDebugValue, useResponder: createDeprecatedResponderListener, @@ -3705,6 +3688,51 @@ var ContextOnlyDispatcher = { ]; } }, + HooksDispatcherOnRerender = { + readContext: readContext, + useCallback: updateCallback, + useContext: readContext, + useEffect: updateEffect, + useImperativeHandle: updateImperativeHandle, + useLayoutEffect: updateLayoutEffect, + useMemo: updateMemo, + useReducer: rerenderReducer, + useRef: updateRef, + useState: rerenderState, + useDebugValue: mountDebugValue, + useResponder: createDeprecatedResponderListener, + useDeferredValue: function(value, config) { + var _rerenderState = rerenderState(value), + prevValue = _rerenderState[0], + setValue = _rerenderState[1]; + updateEffect( + function() { + var previousConfig = ReactCurrentBatchConfig$1.suspense; + ReactCurrentBatchConfig$1.suspense = + void 0 === config ? null : config; + try { + setValue(value); + } finally { + ReactCurrentBatchConfig$1.suspense = previousConfig; + } + }, + [value, config] + ); + return prevValue; + }, + useTransition: function(config) { + var _rerenderState2 = rerenderState(!1), + isPending = _rerenderState2[0]; + _rerenderState2 = _rerenderState2[1]; + return [ + updateCallback(startTransition.bind(null, _rerenderState2, config), [ + _rerenderState2, + config + ]), + isPending + ]; + } + }, hydrationParentFiber = null, nextHydratableInstance = null, isHydrating = !1; @@ -5723,8 +5751,8 @@ function requestCurrentTimeForUpdate() { return (executionContext & (RenderContext | CommitContext)) !== NoContext ? 1073741821 - ((now() / 10) | 0) : 0 !== currentEventTime - ? currentEventTime - : (currentEventTime = 1073741821 - ((now() / 10) | 0)); + ? currentEventTime + : (currentEventTime = 1073741821 - ((now() / 10) | 0)); } function computeExpirationForFiber(currentTime, fiber, suspenseConfig) { fiber = fiber.mode; @@ -5831,9 +5859,10 @@ function getNextRootExpirationTimeToWorkOn(root) { if (0 !== lastExpiredTime) return lastExpiredTime; lastExpiredTime = root.firstPendingTime; if (!isRootSuspendedAtTime(root, lastExpiredTime)) return lastExpiredTime; - lastExpiredTime = root.lastPingedTime; + var lastPingedTime = root.lastPingedTime; root = root.nextKnownPendingLevel; - return lastExpiredTime > root ? lastExpiredTime : root; + root = lastPingedTime > root ? lastPingedTime : root; + return 2 >= root && lastExpiredTime !== root ? 0 : root; } function ensureRootIsScheduled(root) { if (0 !== root.lastExpiredTime) @@ -5855,18 +5884,18 @@ function ensureRootIsScheduled(root) { 1073741823 === expirationTime ? (priorityLevel = 99) : 1 === expirationTime || 2 === expirationTime - ? (priorityLevel = 95) - : ((priorityLevel = - 10 * (1073741821 - expirationTime) - - 10 * (1073741821 - priorityLevel)), - (priorityLevel = - 0 >= priorityLevel - ? 99 - : 250 >= priorityLevel - ? 98 - : 5250 >= priorityLevel - ? 97 - : 95)); + ? (priorityLevel = 95) + : ((priorityLevel = + 10 * (1073741821 - expirationTime) - + 10 * (1073741821 - priorityLevel)), + (priorityLevel = + 0 >= priorityLevel + ? 99 + : 250 >= priorityLevel + ? 98 + : 5250 >= priorityLevel + ? 97 + : 95)); if (null !== existingCallbackNode) { var existingCallbackPriority = root.callbackPriority; if ( @@ -6016,35 +6045,34 @@ function performConcurrentWorkOnRoot(root, didTimeout) { 10 * (1073741821 - workInProgressRootLatestSuspenseTimeout) - now()) : 1073741823 === workInProgressRootLatestProcessedExpirationTime - ? (prevExecutionContext = 0) - : ((prevExecutionContext = - 10 * - (1073741821 - - workInProgressRootLatestProcessedExpirationTime) - - 5e3), - (prevDispatcher = now()), - (expirationTime = - 10 * (1073741821 - expirationTime) - prevDispatcher), - (prevExecutionContext = - prevDispatcher - prevExecutionContext), - 0 > prevExecutionContext && (prevExecutionContext = 0), - (prevExecutionContext = - (120 > prevExecutionContext - ? 120 - : 480 > prevExecutionContext - ? 480 - : 1080 > prevExecutionContext - ? 1080 - : 1920 > prevExecutionContext - ? 1920 - : 3e3 > prevExecutionContext - ? 3e3 - : 4320 > prevExecutionContext - ? 4320 - : 1960 * ceil(prevExecutionContext / 1960)) - - prevExecutionContext), - expirationTime < prevExecutionContext && - (prevExecutionContext = expirationTime)); + ? (prevExecutionContext = 0) + : ((prevExecutionContext = + 10 * + (1073741821 - + workInProgressRootLatestProcessedExpirationTime) - + 5e3), + (prevDispatcher = now()), + (expirationTime = + 10 * (1073741821 - expirationTime) - prevDispatcher), + (prevExecutionContext = prevDispatcher - prevExecutionContext), + 0 > prevExecutionContext && (prevExecutionContext = 0), + (prevExecutionContext = + (120 > prevExecutionContext + ? 120 + : 480 > prevExecutionContext + ? 480 + : 1080 > prevExecutionContext + ? 1080 + : 1920 > prevExecutionContext + ? 1920 + : 3e3 > prevExecutionContext + ? 3e3 + : 4320 > prevExecutionContext + ? 4320 + : 1960 * ceil(prevExecutionContext / 1960)) - + prevExecutionContext), + expirationTime < prevExecutionContext && + (prevExecutionContext = expirationTime)); if (10 < prevExecutionContext) { root.timeoutHandle = scheduleTimeout( commitRoot.bind(null, root), @@ -6199,7 +6227,20 @@ function handleError(root$jscomp$0, thrownValue) { do { try { resetContextDependencies(); - resetHooks(); + ReactCurrentDispatcher$1.current = ContextOnlyDispatcher; + if (didScheduleRenderPhaseUpdate) + for ( + var hook = currentlyRenderingFiber$1.memoizedState; + null !== hook; + + ) { + var queue = hook.queue; + null !== queue && (queue.pending = null); + hook = hook.next; + } + renderExpirationTime$1 = 0; + workInProgressHook = currentHook = currentlyRenderingFiber$1 = null; + didScheduleRenderPhaseUpdate = !1; if (null === workInProgress || null === workInProgress.return) return ( (workInProgressRootExitStatus = RootFatalErrored), @@ -6242,10 +6283,10 @@ function handleError(root$jscomp$0, thrownValue) { void 0 === props.fallback ? !1 : !0 !== props.unstable_avoidThisFallback - ? !0 - : hasInvisibleParentBoundary - ? !1 - : !0; + ? !0 + : hasInvisibleParentBoundary + ? !1 + : !0; } } if (JSCompiler_temp) { @@ -6752,10 +6793,7 @@ function pingSuspendedRoot(root, thenable, suspendedTime) { : isRootSuspendedAtTime(root, suspendedTime) && ((thenable = root.lastPingedTime), (0 !== thenable && thenable < suspendedTime) || - ((root.lastPingedTime = suspendedTime), - root.finishedExpirationTime === suspendedTime && - ((root.finishedExpirationTime = 0), (root.finishedWork = null)), - ensureRootIsScheduled(root))); + ((root.lastPingedTime = suspendedTime), ensureRootIsScheduled(root))); } function resolveRetryThenable(boundaryFiber, thenable) { var retryCache = boundaryFiber.stateNode; @@ -6890,7 +6928,8 @@ beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { void 0 === renderState.$$typeof ) { workInProgress.tag = 1; - resetHooks(); + workInProgress.memoizedState = null; + workInProgress.updateQueue = null; if (isContextProvider(updateExpirationTime)) { var hasContext = !0; pushContextProvider(workInProgress); @@ -7163,7 +7202,7 @@ beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { pushProvider(workInProgress, hasContext); if (null !== getDerivedStateFromProps) { var oldValue = getDerivedStateFromProps.value; - hasContext = is$1(oldValue, hasContext) + hasContext = objectIs(oldValue, hasContext) ? 0 : ("function" === typeof updateExpirationTime._calculateChangedBits ? updateExpirationTime._calculateChangedBits( @@ -7718,8 +7757,8 @@ function findNodeHandle(componentOrHandle) { return null == componentOrHandle ? componentOrHandle : componentOrHandle.canonical - ? componentOrHandle.canonical._nativeTag - : componentOrHandle._nativeTag; + ? componentOrHandle.canonical._nativeTag + : componentOrHandle._nativeTag; } batchedUpdatesImpl = function(fn, a) { var prevExecutionContext = executionContext; @@ -7842,8 +7881,8 @@ var roots = new Map(), return null == componentOrHandle ? componentOrHandle : componentOrHandle.canonical - ? componentOrHandle.canonical - : componentOrHandle; + ? componentOrHandle.canonical + : componentOrHandle; }, findNodeHandle: findNodeHandle, dispatchCommand: function(handle, command, args) { @@ -8027,7 +8066,7 @@ var roots = new Map(), throw Error("getInspectorDataForViewTag() is not available in production"); }, bundleType: 0, - version: "16.12.0-experimental-19f6fe170", + version: "16.12.0-experimental-241c4467e", rendererPackageName: "react-native-renderer" }); var ReactNativeRenderer$2 = { default: ReactNativeRenderer }, diff --git a/Libraries/Renderer/implementations/ReactNativeRenderer-prod.js b/Libraries/Renderer/implementations/ReactNativeRenderer-prod.js index df962ae5da..4cca89d02d 100644 --- a/Libraries/Renderer/implementations/ReactNativeRenderer-prod.js +++ b/Libraries/Renderer/implementations/ReactNativeRenderer-prod.js @@ -349,8 +349,8 @@ function SyntheticEvent( ((targetInst = dispatchConfig[propName]) ? (this[propName] = targetInst(nativeEvent)) : "target" === propName - ? (this.target = nativeEventTarget) - : (this[propName] = nativeEvent[propName])); + ? (this.target = nativeEventTarget) + : (this[propName] = nativeEvent[propName])); this.isDefaultPrevented = (null != nativeEvent.defaultPrevented ? nativeEvent.defaultPrevented : !1 === nativeEvent.returnValue) @@ -563,10 +563,10 @@ function accumulate(current, next) { return null == current ? next : Array.isArray(current) - ? current.concat(next) - : Array.isArray(next) - ? [current].concat(next) - : [current, next]; + ? current.concat(next) + : Array.isArray(next) + ? [current].concat(next) + : [current, next]; } var responderInst = null, trackedTouchCount = 0; @@ -668,10 +668,10 @@ var eventTypes = { var shouldSetEventType = isStartish(topLevelType) ? eventTypes.startShouldSetResponder : isMoveish(topLevelType) - ? eventTypes.moveShouldSetResponder - : "topSelectionChange" === topLevelType - ? eventTypes.selectionChangeShouldSetResponder - : eventTypes.scrollShouldSetResponder; + ? eventTypes.moveShouldSetResponder + : "topSelectionChange" === topLevelType + ? eventTypes.selectionChangeShouldSetResponder + : eventTypes.scrollShouldSetResponder; if (responderInst) b: { var JSCompiler_temp = responderInst; @@ -825,10 +825,10 @@ var eventTypes = { (shouldSetEventType = shouldSetEventType ? eventTypes.responderStart : JSCompiler_temp - ? eventTypes.responderMove - : targetInst - ? eventTypes.responderEnd - : null) + ? eventTypes.responderMove + : targetInst + ? eventTypes.responderEnd + : null) ) (shouldSetEventType = ResponderSyntheticEvent.getPooled( shouldSetEventType, @@ -891,8 +891,8 @@ var eventTypes = { (topLevelType = shouldSetEventType ? eventTypes.responderTerminate : topLevelType - ? eventTypes.responderRelease - : null) + ? eventTypes.responderRelease + : null) ) (nativeEvent = ResponderSyntheticEvent.getPooled( topLevelType, @@ -1365,8 +1365,8 @@ function diffNestedProperty( return nextProp ? addNestedProperty(updatePayload, nextProp, validAttributes) : prevProp - ? clearNestedProperty(updatePayload, prevProp, validAttributes) - : updatePayload; + ? clearNestedProperty(updatePayload, prevProp, validAttributes) + : updatePayload; if (!Array.isArray(prevProp) && !Array.isArray(nextProp)) return diffProperties(updatePayload, prevProp, nextProp, validAttributes); if (Array.isArray(prevProp) && Array.isArray(nextProp)) { @@ -1877,10 +1877,10 @@ function flushSyncCallbackQueueImpl() { function is(x, y) { return (x === y && (0 !== x || 1 / x === 1 / y)) || (x !== x && y !== y); } -var is$1 = "function" === typeof Object.is ? Object.is : is, +var objectIs = "function" === typeof Object.is ? Object.is : is, hasOwnProperty = Object.prototype.hasOwnProperty; function shallowEqual(objA, objB) { - if (is$1(objA, objB)) return !0; + if (objectIs(objA, objB)) return !0; if ( "object" !== typeof objA || null === objA || @@ -1894,7 +1894,7 @@ function shallowEqual(objA, objB) { for (keysB = 0; keysB < keysA.length; keysB++) if ( !hasOwnProperty.call(objB, keysA[keysB]) || - !is$1(objA[keysA[keysB]], objB[keysA[keysB]]) + !objectIs(objA[keysA[keysB]], objB[keysA[keysB]]) ) return !1; return !0; @@ -2246,8 +2246,8 @@ function checkShouldComponentUpdate( return "function" === typeof workInProgress.shouldComponentUpdate ? workInProgress.shouldComponentUpdate(newProps, newState, nextContext) : ctor.prototype && ctor.prototype.isPureReactComponent - ? !shallowEqual(oldProps, newProps) || !shallowEqual(oldState, newState) - : !0; + ? !shallowEqual(oldProps, newProps) || !shallowEqual(oldState, newState) + : !0; } function constructClassInstance(workInProgress, ctor, props) { var isLegacyContextConsumer = !1, @@ -3142,9 +3142,7 @@ var ReactCurrentDispatcher$1 = ReactSharedInternals.ReactCurrentDispatcher, currentlyRenderingFiber$1 = null, currentHook = null, workInProgressHook = null, - didScheduleRenderPhaseUpdate = !1, - renderPhaseUpdates = null, - numberOfReRenders = 0; + didScheduleRenderPhaseUpdate = !1; function throwInvalidHookError() { throw Error( "Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons:\n1. You might have mismatching versions of React and the renderer (such as React DOM)\n2. You might be breaking the Rules of Hooks\n3. You might have more than one copy of React in the same app\nSee https://fb.me/react-invalid-hook-call for tips about how to debug and fix this problem." @@ -3153,7 +3151,7 @@ function throwInvalidHookError() { function areHookInputsEqual(nextDeps, prevDeps) { if (null === prevDeps) return !1; for (var i = 0; i < prevDeps.length && i < nextDeps.length; i++) - if (!is$1(nextDeps[i], prevDeps[i])) return !1; + if (!objectIs(nextDeps[i], prevDeps[i])) return !1; return !0; } function renderWithHooks( @@ -3174,36 +3172,32 @@ function renderWithHooks( ? HooksDispatcherOnMount : HooksDispatcherOnUpdate; current = Component(props, secondArg); - if (didScheduleRenderPhaseUpdate) { - do - (didScheduleRenderPhaseUpdate = !1), - (numberOfReRenders += 1), - (workInProgressHook = currentHook = null), - (workInProgress.updateQueue = null), - (ReactCurrentDispatcher$1.current = HooksDispatcherOnUpdate), - (current = Component(props, secondArg)); - while (didScheduleRenderPhaseUpdate); - renderPhaseUpdates = null; - numberOfReRenders = 0; + if (workInProgress.expirationTime === renderExpirationTime$1) { + nextRenderExpirationTime = 0; + do { + workInProgress.expirationTime = 0; + if (!(25 > nextRenderExpirationTime)) + throw Error( + "Too many re-renders. React limits the number of renders to prevent an infinite loop." + ); + nextRenderExpirationTime += 1; + workInProgressHook = currentHook = null; + workInProgress.updateQueue = null; + ReactCurrentDispatcher$1.current = HooksDispatcherOnRerender; + current = Component(props, secondArg); + } while (workInProgress.expirationTime === renderExpirationTime$1); } ReactCurrentDispatcher$1.current = ContextOnlyDispatcher; workInProgress = null !== currentHook && null !== currentHook.next; renderExpirationTime$1 = 0; workInProgressHook = currentHook = currentlyRenderingFiber$1 = null; + didScheduleRenderPhaseUpdate = !1; if (workInProgress) throw Error( "Rendered fewer hooks than expected. This may be caused by an accidental early return statement." ); return current; } -function resetHooks() { - ReactCurrentDispatcher$1.current = ContextOnlyDispatcher; - renderExpirationTime$1 = 0; - workInProgressHook = currentHook = currentlyRenderingFiber$1 = null; - didScheduleRenderPhaseUpdate = !1; - renderPhaseUpdates = null; - numberOfReRenders = 0; -} function mountWorkInProgressHook() { var hook = { memoizedState: null, @@ -3258,57 +3252,36 @@ function updateReducer(reducer) { "Should have a queue. This is likely a bug in React. Please file an issue." ); queue.lastRenderedReducer = reducer; - if (0 < numberOfReRenders) { - var _dispatch = queue.dispatch; - if (null !== renderPhaseUpdates) { - var firstRenderPhaseUpdate = renderPhaseUpdates.get(queue); - if (void 0 !== firstRenderPhaseUpdate) { - renderPhaseUpdates.delete(queue); - var newState = hook.memoizedState; - do - (newState = reducer(newState, firstRenderPhaseUpdate.action)), - (firstRenderPhaseUpdate = firstRenderPhaseUpdate.next); - while (null !== firstRenderPhaseUpdate); - is$1(newState, hook.memoizedState) || (didReceiveUpdate = !0); - hook.memoizedState = newState; - null === hook.baseQueue && (hook.baseState = newState); - queue.lastRenderedState = newState; - return [newState, _dispatch]; - } + var current = currentHook, + baseQueue = current.baseQueue, + pendingQueue = queue.pending; + if (null !== pendingQueue) { + if (null !== baseQueue) { + var baseFirst = baseQueue.next; + baseQueue.next = pendingQueue.next; + pendingQueue.next = baseFirst; } - return [hook.memoizedState, _dispatch]; - } - newState = currentHook; - _dispatch = newState.baseQueue; - firstRenderPhaseUpdate = queue.pending; - if (null !== firstRenderPhaseUpdate) { - if (null !== _dispatch) { - var baseFirst = _dispatch.next; - _dispatch.next = firstRenderPhaseUpdate.next; - firstRenderPhaseUpdate.next = baseFirst; - } - newState.baseQueue = _dispatch = firstRenderPhaseUpdate; + current.baseQueue = baseQueue = pendingQueue; queue.pending = null; } - if (null !== _dispatch) { - _dispatch = _dispatch.next; - newState = newState.baseState; - var newBaseQueueLast = (baseFirst = firstRenderPhaseUpdate = null), - _update = _dispatch; + if (null !== baseQueue) { + baseQueue = baseQueue.next; + current = current.baseState; + var newBaseQueueLast = (baseFirst = pendingQueue = null), + update = baseQueue; do { - var updateExpirationTime = _update.expirationTime; + var updateExpirationTime = update.expirationTime; if (updateExpirationTime < renderExpirationTime$1) { var clone = { - expirationTime: _update.expirationTime, - suspenseConfig: _update.suspenseConfig, - action: _update.action, - eagerReducer: _update.eagerReducer, - eagerState: _update.eagerState, + expirationTime: update.expirationTime, + suspenseConfig: update.suspenseConfig, + action: update.action, + eagerReducer: update.eagerReducer, + eagerState: update.eagerState, next: null }; null === newBaseQueueLast - ? ((baseFirst = newBaseQueueLast = clone), - (firstRenderPhaseUpdate = newState)) + ? ((baseFirst = newBaseQueueLast = clone), (pendingQueue = current)) : (newBaseQueueLast = newBaseQueueLast.next = clone); updateExpirationTime > currentlyRenderingFiber$1.expirationTime && ((currentlyRenderingFiber$1.expirationTime = updateExpirationTime), @@ -3317,33 +3290,56 @@ function updateReducer(reducer) { null !== newBaseQueueLast && (newBaseQueueLast = newBaseQueueLast.next = { expirationTime: 1073741823, - suspenseConfig: _update.suspenseConfig, - action: _update.action, - eagerReducer: _update.eagerReducer, - eagerState: _update.eagerState, + suspenseConfig: update.suspenseConfig, + action: update.action, + eagerReducer: update.eagerReducer, + eagerState: update.eagerState, next: null }), markRenderEventTimeAndConfig( updateExpirationTime, - _update.suspenseConfig + update.suspenseConfig ), - (newState = - _update.eagerReducer === reducer - ? _update.eagerState - : reducer(newState, _update.action)); - _update = _update.next; - } while (null !== _update && _update !== _dispatch); + (current = + update.eagerReducer === reducer + ? update.eagerState + : reducer(current, update.action)); + update = update.next; + } while (null !== update && update !== baseQueue); null === newBaseQueueLast - ? (firstRenderPhaseUpdate = newState) + ? (pendingQueue = current) : (newBaseQueueLast.next = baseFirst); - is$1(newState, hook.memoizedState) || (didReceiveUpdate = !0); - hook.memoizedState = newState; - hook.baseState = firstRenderPhaseUpdate; + objectIs(current, hook.memoizedState) || (didReceiveUpdate = !0); + hook.memoizedState = current; + hook.baseState = pendingQueue; hook.baseQueue = newBaseQueueLast; - queue.lastRenderedState = newState; + queue.lastRenderedState = current; } return [hook.memoizedState, queue.dispatch]; } +function rerenderReducer(reducer) { + var hook = updateWorkInProgressHook(), + queue = hook.queue; + if (null === queue) + throw Error( + "Should have a queue. This is likely a bug in React. Please file an issue." + ); + queue.lastRenderedReducer = reducer; + var dispatch = queue.dispatch, + lastRenderPhaseUpdate = queue.pending, + newState = hook.memoizedState; + if (null !== lastRenderPhaseUpdate) { + queue.pending = null; + var update = (lastRenderPhaseUpdate = lastRenderPhaseUpdate.next); + do (newState = reducer(newState, update.action)), (update = update.next); + while (update !== lastRenderPhaseUpdate); + objectIs(newState, hook.memoizedState) || (didReceiveUpdate = !0); + hook.memoizedState = newState; + null === hook.baseQueue && (hook.baseState = newState); + queue.lastRenderedState = newState; + } + return [newState, dispatch]; +} function mountState(initialState) { var hook = mountWorkInProgressHook(); "function" === typeof initialState && (initialState = initialState()); @@ -3364,6 +3360,9 @@ function mountState(initialState) { function updateState(initialState) { return updateReducer(basicStateReducer, initialState); } +function rerenderState(initialState) { + return rerenderReducer(basicStateReducer, initialState); +} function pushEffect(tag, create, destroy, deps) { tag = { tag: tag, create: create, destroy: destroy, deps: deps, next: null }; create = currentlyRenderingFiber$1.updateQueue; @@ -3380,6 +3379,9 @@ function pushEffect(tag, create, destroy, deps) { (create.lastEffect = tag))); return tag; } +function updateRef() { + return updateWorkInProgressHook().memoizedState; +} function mountEffectImpl(fiberEffectTag, hookEffectTag, create, deps) { var hook = mountWorkInProgressHook(); currentlyRenderingFiber$1.effectTag |= fiberEffectTag; @@ -3411,6 +3413,9 @@ function mountEffect(create, deps) { function updateEffect(create, deps) { return updateEffectImpl(516, 192, create, deps); } +function updateLayoutEffect(create, deps) { + return updateEffectImpl(4, 36, create, deps); +} function imperativeHandleEffect(create, ref) { if ("function" === typeof ref) return ( @@ -3429,6 +3434,15 @@ function imperativeHandleEffect(create, ref) { } ); } +function updateImperativeHandle(ref, create, deps) { + deps = null !== deps && void 0 !== deps ? deps.concat([ref]) : null; + return updateEffectImpl( + 4, + 36, + imperativeHandleEffect.bind(null, create, ref), + deps + ); +} function mountDebugValue() {} function mountCallback(callback, deps) { mountWorkInProgressHook().memoizedState = [ @@ -3450,6 +3464,20 @@ function updateCallback(callback, deps) { hook.memoizedState = [callback, deps]; return callback; } +function updateMemo(nextCreate, deps) { + var hook = updateWorkInProgressHook(); + deps = void 0 === deps ? null : deps; + var prevState = hook.memoizedState; + if ( + null !== prevState && + null !== deps && + areHookInputsEqual(deps, prevState[1]) + ) + return prevState[0]; + nextCreate = nextCreate(); + hook.memoizedState = [nextCreate, deps]; + return nextCreate; +} function startTransition(setPending, config, callback) { var priorityLevel = getCurrentPriorityLevel(); runWithPriority(98 > priorityLevel ? 98 : priorityLevel, function() { @@ -3466,62 +3494,42 @@ function startTransition(setPending, config, callback) { }); } function dispatchAction(fiber, queue, action) { - if (!(25 > numberOfReRenders)) - throw Error( - "Too many re-renders. React limits the number of renders to prevent an infinite loop." - ); - var alternate = fiber.alternate; + var currentTime = requestCurrentTimeForUpdate(), + suspenseConfig = ReactCurrentBatchConfig.suspense; + currentTime = computeExpirationForFiber(currentTime, fiber, suspenseConfig); + suspenseConfig = { + expirationTime: currentTime, + suspenseConfig: suspenseConfig, + action: action, + eagerReducer: null, + eagerState: null, + next: null + }; + var pending = queue.pending; + null === pending + ? (suspenseConfig.next = suspenseConfig) + : ((suspenseConfig.next = pending.next), (pending.next = suspenseConfig)); + queue.pending = suspenseConfig; + pending = fiber.alternate; if ( fiber === currentlyRenderingFiber$1 || - (null !== alternate && alternate === currentlyRenderingFiber$1) + (null !== pending && pending === currentlyRenderingFiber$1) ) - if ( - ((didScheduleRenderPhaseUpdate = !0), - (fiber = { - expirationTime: renderExpirationTime$1, - suspenseConfig: null, - action: action, - eagerReducer: null, - eagerState: null, - next: null - }), - null === renderPhaseUpdates && (renderPhaseUpdates = new Map()), - (action = renderPhaseUpdates.get(queue)), - void 0 === action) - ) - renderPhaseUpdates.set(queue, fiber); - else { - for (queue = action; null !== queue.next; ) queue = queue.next; - queue.next = fiber; - } + (didScheduleRenderPhaseUpdate = !0), + (suspenseConfig.expirationTime = renderExpirationTime$1), + (currentlyRenderingFiber$1.expirationTime = renderExpirationTime$1); else { - var currentTime = requestCurrentTimeForUpdate(), - suspenseConfig = ReactCurrentBatchConfig.suspense; - currentTime = computeExpirationForFiber(currentTime, fiber, suspenseConfig); - suspenseConfig = { - expirationTime: currentTime, - suspenseConfig: suspenseConfig, - action: action, - eagerReducer: null, - eagerState: null, - next: null - }; - var pending = queue.pending; - null === pending - ? (suspenseConfig.next = suspenseConfig) - : ((suspenseConfig.next = pending.next), (pending.next = suspenseConfig)); - queue.pending = suspenseConfig; if ( 0 === fiber.expirationTime && - (null === alternate || 0 === alternate.expirationTime) && - ((alternate = queue.lastRenderedReducer), null !== alternate) + (null === pending || 0 === pending.expirationTime) && + ((pending = queue.lastRenderedReducer), null !== pending) ) try { var currentState = queue.lastRenderedState, - eagerState = alternate(currentState, action); - suspenseConfig.eagerReducer = alternate; + eagerState = pending(currentState, action); + suspenseConfig.eagerReducer = pending; suspenseConfig.eagerState = eagerState; - if (is$1(eagerState, currentState)) return; + if (objectIs(eagerState, currentState)) return; } catch (error) { } finally { } @@ -3630,36 +3638,11 @@ var ContextOnlyDispatcher = { useCallback: updateCallback, useContext: readContext, useEffect: updateEffect, - useImperativeHandle: function(ref, create, deps) { - deps = null !== deps && void 0 !== deps ? deps.concat([ref]) : null; - return updateEffectImpl( - 4, - 36, - imperativeHandleEffect.bind(null, create, ref), - deps - ); - }, - useLayoutEffect: function(create, deps) { - return updateEffectImpl(4, 36, create, deps); - }, - useMemo: function(nextCreate, deps) { - var hook = updateWorkInProgressHook(); - deps = void 0 === deps ? null : deps; - var prevState = hook.memoizedState; - if ( - null !== prevState && - null !== deps && - areHookInputsEqual(deps, prevState[1]) - ) - return prevState[0]; - nextCreate = nextCreate(); - hook.memoizedState = [nextCreate, deps]; - return nextCreate; - }, + useImperativeHandle: updateImperativeHandle, + useLayoutEffect: updateLayoutEffect, + useMemo: updateMemo, useReducer: updateReducer, - useRef: function() { - return updateWorkInProgressHook().memoizedState; - }, + useRef: updateRef, useState: updateState, useDebugValue: mountDebugValue, useResponder: createDeprecatedResponderListener, @@ -3695,6 +3678,51 @@ var ContextOnlyDispatcher = { ]; } }, + HooksDispatcherOnRerender = { + readContext: readContext, + useCallback: updateCallback, + useContext: readContext, + useEffect: updateEffect, + useImperativeHandle: updateImperativeHandle, + useLayoutEffect: updateLayoutEffect, + useMemo: updateMemo, + useReducer: rerenderReducer, + useRef: updateRef, + useState: rerenderState, + useDebugValue: mountDebugValue, + useResponder: createDeprecatedResponderListener, + useDeferredValue: function(value, config) { + var _rerenderState = rerenderState(value), + prevValue = _rerenderState[0], + setValue = _rerenderState[1]; + updateEffect( + function() { + var previousConfig = ReactCurrentBatchConfig$1.suspense; + ReactCurrentBatchConfig$1.suspense = + void 0 === config ? null : config; + try { + setValue(value); + } finally { + ReactCurrentBatchConfig$1.suspense = previousConfig; + } + }, + [value, config] + ); + return prevValue; + }, + useTransition: function(config) { + var _rerenderState2 = rerenderState(!1), + isPending = _rerenderState2[0]; + _rerenderState2 = _rerenderState2[1]; + return [ + updateCallback(startTransition.bind(null, _rerenderState2, config), [ + _rerenderState2, + config + ]), + isPending + ]; + } + }, hydrationParentFiber = null, nextHydratableInstance = null, isHydrating = !1; @@ -5713,8 +5741,8 @@ function requestCurrentTimeForUpdate() { return (executionContext & (RenderContext | CommitContext)) !== NoContext ? 1073741821 - ((now() / 10) | 0) : 0 !== currentEventTime - ? currentEventTime - : (currentEventTime = 1073741821 - ((now() / 10) | 0)); + ? currentEventTime + : (currentEventTime = 1073741821 - ((now() / 10) | 0)); } function computeExpirationForFiber(currentTime, fiber, suspenseConfig) { fiber = fiber.mode; @@ -5821,9 +5849,10 @@ function getNextRootExpirationTimeToWorkOn(root) { if (0 !== lastExpiredTime) return lastExpiredTime; lastExpiredTime = root.firstPendingTime; if (!isRootSuspendedAtTime(root, lastExpiredTime)) return lastExpiredTime; - lastExpiredTime = root.lastPingedTime; + var lastPingedTime = root.lastPingedTime; root = root.nextKnownPendingLevel; - return lastExpiredTime > root ? lastExpiredTime : root; + root = lastPingedTime > root ? lastPingedTime : root; + return 2 >= root && lastExpiredTime !== root ? 0 : root; } function ensureRootIsScheduled(root) { if (0 !== root.lastExpiredTime) @@ -5845,18 +5874,18 @@ function ensureRootIsScheduled(root) { 1073741823 === expirationTime ? (priorityLevel = 99) : 1 === expirationTime || 2 === expirationTime - ? (priorityLevel = 95) - : ((priorityLevel = - 10 * (1073741821 - expirationTime) - - 10 * (1073741821 - priorityLevel)), - (priorityLevel = - 0 >= priorityLevel - ? 99 - : 250 >= priorityLevel - ? 98 - : 5250 >= priorityLevel - ? 97 - : 95)); + ? (priorityLevel = 95) + : ((priorityLevel = + 10 * (1073741821 - expirationTime) - + 10 * (1073741821 - priorityLevel)), + (priorityLevel = + 0 >= priorityLevel + ? 99 + : 250 >= priorityLevel + ? 98 + : 5250 >= priorityLevel + ? 97 + : 95)); if (null !== existingCallbackNode) { var existingCallbackPriority = root.callbackPriority; if ( @@ -6006,35 +6035,34 @@ function performConcurrentWorkOnRoot(root, didTimeout) { 10 * (1073741821 - workInProgressRootLatestSuspenseTimeout) - now()) : 1073741823 === workInProgressRootLatestProcessedExpirationTime - ? (prevExecutionContext = 0) - : ((prevExecutionContext = - 10 * - (1073741821 - - workInProgressRootLatestProcessedExpirationTime) - - 5e3), - (prevDispatcher = now()), - (expirationTime = - 10 * (1073741821 - expirationTime) - prevDispatcher), - (prevExecutionContext = - prevDispatcher - prevExecutionContext), - 0 > prevExecutionContext && (prevExecutionContext = 0), - (prevExecutionContext = - (120 > prevExecutionContext - ? 120 - : 480 > prevExecutionContext - ? 480 - : 1080 > prevExecutionContext - ? 1080 - : 1920 > prevExecutionContext - ? 1920 - : 3e3 > prevExecutionContext - ? 3e3 - : 4320 > prevExecutionContext - ? 4320 - : 1960 * ceil(prevExecutionContext / 1960)) - - prevExecutionContext), - expirationTime < prevExecutionContext && - (prevExecutionContext = expirationTime)); + ? (prevExecutionContext = 0) + : ((prevExecutionContext = + 10 * + (1073741821 - + workInProgressRootLatestProcessedExpirationTime) - + 5e3), + (prevDispatcher = now()), + (expirationTime = + 10 * (1073741821 - expirationTime) - prevDispatcher), + (prevExecutionContext = prevDispatcher - prevExecutionContext), + 0 > prevExecutionContext && (prevExecutionContext = 0), + (prevExecutionContext = + (120 > prevExecutionContext + ? 120 + : 480 > prevExecutionContext + ? 480 + : 1080 > prevExecutionContext + ? 1080 + : 1920 > prevExecutionContext + ? 1920 + : 3e3 > prevExecutionContext + ? 3e3 + : 4320 > prevExecutionContext + ? 4320 + : 1960 * ceil(prevExecutionContext / 1960)) - + prevExecutionContext), + expirationTime < prevExecutionContext && + (prevExecutionContext = expirationTime)); if (10 < prevExecutionContext) { root.timeoutHandle = scheduleTimeout( commitRoot.bind(null, root), @@ -6189,7 +6217,20 @@ function handleError(root$jscomp$0, thrownValue) { do { try { resetContextDependencies(); - resetHooks(); + ReactCurrentDispatcher$1.current = ContextOnlyDispatcher; + if (didScheduleRenderPhaseUpdate) + for ( + var hook = currentlyRenderingFiber$1.memoizedState; + null !== hook; + + ) { + var queue = hook.queue; + null !== queue && (queue.pending = null); + hook = hook.next; + } + renderExpirationTime$1 = 0; + workInProgressHook = currentHook = currentlyRenderingFiber$1 = null; + didScheduleRenderPhaseUpdate = !1; if (null === workInProgress || null === workInProgress.return) return ( (workInProgressRootExitStatus = RootFatalErrored), @@ -6232,10 +6273,10 @@ function handleError(root$jscomp$0, thrownValue) { void 0 === props.fallback ? !1 : !0 !== props.unstable_avoidThisFallback - ? !0 - : hasInvisibleParentBoundary - ? !1 - : !0; + ? !0 + : hasInvisibleParentBoundary + ? !1 + : !0; } } if (JSCompiler_temp) { @@ -6742,10 +6783,7 @@ function pingSuspendedRoot(root, thenable, suspendedTime) { : isRootSuspendedAtTime(root, suspendedTime) && ((thenable = root.lastPingedTime), (0 !== thenable && thenable < suspendedTime) || - ((root.lastPingedTime = suspendedTime), - root.finishedExpirationTime === suspendedTime && - ((root.finishedExpirationTime = 0), (root.finishedWork = null)), - ensureRootIsScheduled(root))); + ((root.lastPingedTime = suspendedTime), ensureRootIsScheduled(root))); } function resolveRetryThenable(boundaryFiber, thenable) { var retryCache = boundaryFiber.stateNode; @@ -6880,7 +6918,8 @@ beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { void 0 === renderState.$$typeof ) { workInProgress.tag = 1; - resetHooks(); + workInProgress.memoizedState = null; + workInProgress.updateQueue = null; if (isContextProvider(updateExpirationTime)) { var hasContext = !0; pushContextProvider(workInProgress); @@ -7153,7 +7192,7 @@ beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { pushProvider(workInProgress, hasContext); if (null !== getDerivedStateFromProps) { var oldValue = getDerivedStateFromProps.value; - hasContext = is$1(oldValue, hasContext) + hasContext = objectIs(oldValue, hasContext) ? 0 : ("function" === typeof updateExpirationTime._calculateChangedBits ? updateExpirationTime._calculateChangedBits( @@ -7708,8 +7747,8 @@ function findNodeHandle(componentOrHandle) { return null == componentOrHandle ? componentOrHandle : componentOrHandle.canonical - ? componentOrHandle.canonical._nativeTag - : componentOrHandle._nativeTag; + ? componentOrHandle.canonical._nativeTag + : componentOrHandle._nativeTag; } batchedUpdatesImpl = function(fn, a) { var prevExecutionContext = executionContext; @@ -7832,8 +7871,8 @@ var roots = new Map(), return null == componentOrHandle ? componentOrHandle : componentOrHandle.canonical - ? componentOrHandle.canonical - : componentOrHandle; + ? componentOrHandle.canonical + : componentOrHandle; }, findNodeHandle: findNodeHandle, dispatchCommand: function(handle, command, args) { @@ -8017,7 +8056,7 @@ var roots = new Map(), throw Error("getInspectorDataForViewTag() is not available in production"); }, bundleType: 0, - version: "16.12.0-19f6fe170", + version: "16.12.0-241c4467e", rendererPackageName: "react-native-renderer" }); var ReactNativeRenderer$2 = { default: ReactNativeRenderer }, diff --git a/Libraries/Renderer/implementations/ReactNativeRenderer-profiling.fb.js b/Libraries/Renderer/implementations/ReactNativeRenderer-profiling.fb.js index 955ccea4e4..d6dac8e2a0 100644 --- a/Libraries/Renderer/implementations/ReactNativeRenderer-profiling.fb.js +++ b/Libraries/Renderer/implementations/ReactNativeRenderer-profiling.fb.js @@ -349,8 +349,8 @@ function SyntheticEvent( ((targetInst = dispatchConfig[propName]) ? (this[propName] = targetInst(nativeEvent)) : "target" === propName - ? (this.target = nativeEventTarget) - : (this[propName] = nativeEvent[propName])); + ? (this.target = nativeEventTarget) + : (this[propName] = nativeEvent[propName])); this.isDefaultPrevented = (null != nativeEvent.defaultPrevented ? nativeEvent.defaultPrevented : !1 === nativeEvent.returnValue) @@ -563,10 +563,10 @@ function accumulate(current, next) { return null == current ? next : Array.isArray(current) - ? current.concat(next) - : Array.isArray(next) - ? [current].concat(next) - : [current, next]; + ? current.concat(next) + : Array.isArray(next) + ? [current].concat(next) + : [current, next]; } var responderInst = null, trackedTouchCount = 0; @@ -668,10 +668,10 @@ var eventTypes = { var shouldSetEventType = isStartish(topLevelType) ? eventTypes.startShouldSetResponder : isMoveish(topLevelType) - ? eventTypes.moveShouldSetResponder - : "topSelectionChange" === topLevelType - ? eventTypes.selectionChangeShouldSetResponder - : eventTypes.scrollShouldSetResponder; + ? eventTypes.moveShouldSetResponder + : "topSelectionChange" === topLevelType + ? eventTypes.selectionChangeShouldSetResponder + : eventTypes.scrollShouldSetResponder; if (responderInst) b: { var JSCompiler_temp = responderInst; @@ -825,10 +825,10 @@ var eventTypes = { (shouldSetEventType = shouldSetEventType ? eventTypes.responderStart : JSCompiler_temp - ? eventTypes.responderMove - : targetInst - ? eventTypes.responderEnd - : null) + ? eventTypes.responderMove + : targetInst + ? eventTypes.responderEnd + : null) ) (shouldSetEventType = ResponderSyntheticEvent.getPooled( shouldSetEventType, @@ -891,8 +891,8 @@ var eventTypes = { (topLevelType = shouldSetEventType ? eventTypes.responderTerminate : topLevelType - ? eventTypes.responderRelease - : null) + ? eventTypes.responderRelease + : null) ) (nativeEvent = ResponderSyntheticEvent.getPooled( topLevelType, @@ -1376,8 +1376,8 @@ function diffNestedProperty( return nextProp ? addNestedProperty(updatePayload, nextProp, validAttributes) : prevProp - ? clearNestedProperty(updatePayload, prevProp, validAttributes) - : updatePayload; + ? clearNestedProperty(updatePayload, prevProp, validAttributes) + : updatePayload; if (!Array.isArray(prevProp) && !Array.isArray(nextProp)) return diffProperties(updatePayload, prevProp, nextProp, validAttributes); if (Array.isArray(prevProp) && Array.isArray(nextProp)) { @@ -1900,18 +1900,18 @@ function inferPriorityFromExpirationTime(currentTime, expirationTime) { return 0 >= currentTime ? 99 : 250 >= currentTime - ? 98 - : 5250 >= currentTime - ? 97 - : 95; + ? 98 + : 5250 >= currentTime + ? 97 + : 95; } function is(x, y) { return (x === y && (0 !== x || 1 / x === 1 / y)) || (x !== x && y !== y); } -var is$1 = "function" === typeof Object.is ? Object.is : is, +var objectIs = "function" === typeof Object.is ? Object.is : is, hasOwnProperty = Object.prototype.hasOwnProperty; function shallowEqual(objA, objB) { - if (is$1(objA, objB)) return !0; + if (objectIs(objA, objB)) return !0; if ( "object" !== typeof objA || null === objA || @@ -1925,7 +1925,7 @@ function shallowEqual(objA, objB) { for (keysB = 0; keysB < keysA.length; keysB++) if ( !hasOwnProperty.call(objB, keysA[keysB]) || - !is$1(objA[keysA[keysB]], objB[keysA[keysB]]) + !objectIs(objA[keysA[keysB]], objB[keysA[keysB]]) ) return !1; return !0; @@ -2277,8 +2277,8 @@ function checkShouldComponentUpdate( return "function" === typeof workInProgress.shouldComponentUpdate ? workInProgress.shouldComponentUpdate(newProps, newState, nextContext) : ctor.prototype && ctor.prototype.isPureReactComponent - ? !shallowEqual(oldProps, newProps) || !shallowEqual(oldState, newState) - : !0; + ? !shallowEqual(oldProps, newProps) || !shallowEqual(oldState, newState) + : !0; } function constructClassInstance(workInProgress, ctor, props) { var isLegacyContextConsumer = !1, @@ -3173,9 +3173,7 @@ var ReactCurrentDispatcher$1 = ReactSharedInternals.ReactCurrentDispatcher, currentlyRenderingFiber$1 = null, currentHook = null, workInProgressHook = null, - didScheduleRenderPhaseUpdate = !1, - renderPhaseUpdates = null, - numberOfReRenders = 0; + didScheduleRenderPhaseUpdate = !1; function throwInvalidHookError() { throw Error( "Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons:\n1. You might have mismatching versions of React and the renderer (such as React DOM)\n2. You might be breaking the Rules of Hooks\n3. You might have more than one copy of React in the same app\nSee https://fb.me/react-invalid-hook-call for tips about how to debug and fix this problem." @@ -3184,7 +3182,7 @@ function throwInvalidHookError() { function areHookInputsEqual(nextDeps, prevDeps) { if (null === prevDeps) return !1; for (var i = 0; i < prevDeps.length && i < nextDeps.length; i++) - if (!is$1(nextDeps[i], prevDeps[i])) return !1; + if (!objectIs(nextDeps[i], prevDeps[i])) return !1; return !0; } function renderWithHooks( @@ -3205,36 +3203,32 @@ function renderWithHooks( ? HooksDispatcherOnMount : HooksDispatcherOnUpdate; current = Component(props, secondArg); - if (didScheduleRenderPhaseUpdate) { - do - (didScheduleRenderPhaseUpdate = !1), - (numberOfReRenders += 1), - (workInProgressHook = currentHook = null), - (workInProgress.updateQueue = null), - (ReactCurrentDispatcher$1.current = HooksDispatcherOnUpdate), - (current = Component(props, secondArg)); - while (didScheduleRenderPhaseUpdate); - renderPhaseUpdates = null; - numberOfReRenders = 0; + if (workInProgress.expirationTime === renderExpirationTime$1) { + nextRenderExpirationTime = 0; + do { + workInProgress.expirationTime = 0; + if (!(25 > nextRenderExpirationTime)) + throw Error( + "Too many re-renders. React limits the number of renders to prevent an infinite loop." + ); + nextRenderExpirationTime += 1; + workInProgressHook = currentHook = null; + workInProgress.updateQueue = null; + ReactCurrentDispatcher$1.current = HooksDispatcherOnRerender; + current = Component(props, secondArg); + } while (workInProgress.expirationTime === renderExpirationTime$1); } ReactCurrentDispatcher$1.current = ContextOnlyDispatcher; workInProgress = null !== currentHook && null !== currentHook.next; renderExpirationTime$1 = 0; workInProgressHook = currentHook = currentlyRenderingFiber$1 = null; + didScheduleRenderPhaseUpdate = !1; if (workInProgress) throw Error( "Rendered fewer hooks than expected. This may be caused by an accidental early return statement." ); return current; } -function resetHooks() { - ReactCurrentDispatcher$1.current = ContextOnlyDispatcher; - renderExpirationTime$1 = 0; - workInProgressHook = currentHook = currentlyRenderingFiber$1 = null; - didScheduleRenderPhaseUpdate = !1; - renderPhaseUpdates = null; - numberOfReRenders = 0; -} function mountWorkInProgressHook() { var hook = { memoizedState: null, @@ -3289,57 +3283,36 @@ function updateReducer(reducer) { "Should have a queue. This is likely a bug in React. Please file an issue." ); queue.lastRenderedReducer = reducer; - if (0 < numberOfReRenders) { - var _dispatch = queue.dispatch; - if (null !== renderPhaseUpdates) { - var firstRenderPhaseUpdate = renderPhaseUpdates.get(queue); - if (void 0 !== firstRenderPhaseUpdate) { - renderPhaseUpdates.delete(queue); - var newState = hook.memoizedState; - do - (newState = reducer(newState, firstRenderPhaseUpdate.action)), - (firstRenderPhaseUpdate = firstRenderPhaseUpdate.next); - while (null !== firstRenderPhaseUpdate); - is$1(newState, hook.memoizedState) || (didReceiveUpdate = !0); - hook.memoizedState = newState; - null === hook.baseQueue && (hook.baseState = newState); - queue.lastRenderedState = newState; - return [newState, _dispatch]; - } + var current = currentHook, + baseQueue = current.baseQueue, + pendingQueue = queue.pending; + if (null !== pendingQueue) { + if (null !== baseQueue) { + var baseFirst = baseQueue.next; + baseQueue.next = pendingQueue.next; + pendingQueue.next = baseFirst; } - return [hook.memoizedState, _dispatch]; - } - newState = currentHook; - _dispatch = newState.baseQueue; - firstRenderPhaseUpdate = queue.pending; - if (null !== firstRenderPhaseUpdate) { - if (null !== _dispatch) { - var baseFirst = _dispatch.next; - _dispatch.next = firstRenderPhaseUpdate.next; - firstRenderPhaseUpdate.next = baseFirst; - } - newState.baseQueue = _dispatch = firstRenderPhaseUpdate; + current.baseQueue = baseQueue = pendingQueue; queue.pending = null; } - if (null !== _dispatch) { - _dispatch = _dispatch.next; - newState = newState.baseState; - var newBaseQueueLast = (baseFirst = firstRenderPhaseUpdate = null), - _update = _dispatch; + if (null !== baseQueue) { + baseQueue = baseQueue.next; + current = current.baseState; + var newBaseQueueLast = (baseFirst = pendingQueue = null), + update = baseQueue; do { - var updateExpirationTime = _update.expirationTime; + var updateExpirationTime = update.expirationTime; if (updateExpirationTime < renderExpirationTime$1) { var clone = { - expirationTime: _update.expirationTime, - suspenseConfig: _update.suspenseConfig, - action: _update.action, - eagerReducer: _update.eagerReducer, - eagerState: _update.eagerState, + expirationTime: update.expirationTime, + suspenseConfig: update.suspenseConfig, + action: update.action, + eagerReducer: update.eagerReducer, + eagerState: update.eagerState, next: null }; null === newBaseQueueLast - ? ((baseFirst = newBaseQueueLast = clone), - (firstRenderPhaseUpdate = newState)) + ? ((baseFirst = newBaseQueueLast = clone), (pendingQueue = current)) : (newBaseQueueLast = newBaseQueueLast.next = clone); updateExpirationTime > currentlyRenderingFiber$1.expirationTime && ((currentlyRenderingFiber$1.expirationTime = updateExpirationTime), @@ -3348,33 +3321,56 @@ function updateReducer(reducer) { null !== newBaseQueueLast && (newBaseQueueLast = newBaseQueueLast.next = { expirationTime: 1073741823, - suspenseConfig: _update.suspenseConfig, - action: _update.action, - eagerReducer: _update.eagerReducer, - eagerState: _update.eagerState, + suspenseConfig: update.suspenseConfig, + action: update.action, + eagerReducer: update.eagerReducer, + eagerState: update.eagerState, next: null }), markRenderEventTimeAndConfig( updateExpirationTime, - _update.suspenseConfig + update.suspenseConfig ), - (newState = - _update.eagerReducer === reducer - ? _update.eagerState - : reducer(newState, _update.action)); - _update = _update.next; - } while (null !== _update && _update !== _dispatch); + (current = + update.eagerReducer === reducer + ? update.eagerState + : reducer(current, update.action)); + update = update.next; + } while (null !== update && update !== baseQueue); null === newBaseQueueLast - ? (firstRenderPhaseUpdate = newState) + ? (pendingQueue = current) : (newBaseQueueLast.next = baseFirst); - is$1(newState, hook.memoizedState) || (didReceiveUpdate = !0); - hook.memoizedState = newState; - hook.baseState = firstRenderPhaseUpdate; + objectIs(current, hook.memoizedState) || (didReceiveUpdate = !0); + hook.memoizedState = current; + hook.baseState = pendingQueue; hook.baseQueue = newBaseQueueLast; - queue.lastRenderedState = newState; + queue.lastRenderedState = current; } return [hook.memoizedState, queue.dispatch]; } +function rerenderReducer(reducer) { + var hook = updateWorkInProgressHook(), + queue = hook.queue; + if (null === queue) + throw Error( + "Should have a queue. This is likely a bug in React. Please file an issue." + ); + queue.lastRenderedReducer = reducer; + var dispatch = queue.dispatch, + lastRenderPhaseUpdate = queue.pending, + newState = hook.memoizedState; + if (null !== lastRenderPhaseUpdate) { + queue.pending = null; + var update = (lastRenderPhaseUpdate = lastRenderPhaseUpdate.next); + do (newState = reducer(newState, update.action)), (update = update.next); + while (update !== lastRenderPhaseUpdate); + objectIs(newState, hook.memoizedState) || (didReceiveUpdate = !0); + hook.memoizedState = newState; + null === hook.baseQueue && (hook.baseState = newState); + queue.lastRenderedState = newState; + } + return [newState, dispatch]; +} function mountState(initialState) { var hook = mountWorkInProgressHook(); "function" === typeof initialState && (initialState = initialState()); @@ -3395,6 +3391,9 @@ function mountState(initialState) { function updateState(initialState) { return updateReducer(basicStateReducer, initialState); } +function rerenderState(initialState) { + return rerenderReducer(basicStateReducer, initialState); +} function pushEffect(tag, create, destroy, deps) { tag = { tag: tag, create: create, destroy: destroy, deps: deps, next: null }; create = currentlyRenderingFiber$1.updateQueue; @@ -3411,6 +3410,9 @@ function pushEffect(tag, create, destroy, deps) { (create.lastEffect = tag))); return tag; } +function updateRef() { + return updateWorkInProgressHook().memoizedState; +} function mountEffectImpl(fiberEffectTag, hookEffectTag, create, deps) { var hook = mountWorkInProgressHook(); currentlyRenderingFiber$1.effectTag |= fiberEffectTag; @@ -3442,6 +3444,9 @@ function mountEffect(create, deps) { function updateEffect(create, deps) { return updateEffectImpl(516, 192, create, deps); } +function updateLayoutEffect(create, deps) { + return updateEffectImpl(4, 36, create, deps); +} function imperativeHandleEffect(create, ref) { if ("function" === typeof ref) return ( @@ -3460,6 +3465,15 @@ function imperativeHandleEffect(create, ref) { } ); } +function updateImperativeHandle(ref, create, deps) { + deps = null !== deps && void 0 !== deps ? deps.concat([ref]) : null; + return updateEffectImpl( + 4, + 36, + imperativeHandleEffect.bind(null, create, ref), + deps + ); +} function mountDebugValue() {} function mountCallback(callback, deps) { mountWorkInProgressHook().memoizedState = [ @@ -3481,6 +3495,20 @@ function updateCallback(callback, deps) { hook.memoizedState = [callback, deps]; return callback; } +function updateMemo(nextCreate, deps) { + var hook = updateWorkInProgressHook(); + deps = void 0 === deps ? null : deps; + var prevState = hook.memoizedState; + if ( + null !== prevState && + null !== deps && + areHookInputsEqual(deps, prevState[1]) + ) + return prevState[0]; + nextCreate = nextCreate(); + hook.memoizedState = [nextCreate, deps]; + return nextCreate; +} function startTransition(setPending, config, callback) { var priorityLevel = getCurrentPriorityLevel(); runWithPriority(98 > priorityLevel ? 98 : priorityLevel, function() { @@ -3497,62 +3525,42 @@ function startTransition(setPending, config, callback) { }); } function dispatchAction(fiber, queue, action) { - if (!(25 > numberOfReRenders)) - throw Error( - "Too many re-renders. React limits the number of renders to prevent an infinite loop." - ); - var alternate = fiber.alternate; + var currentTime = requestCurrentTimeForUpdate(), + suspenseConfig = ReactCurrentBatchConfig.suspense; + currentTime = computeExpirationForFiber(currentTime, fiber, suspenseConfig); + suspenseConfig = { + expirationTime: currentTime, + suspenseConfig: suspenseConfig, + action: action, + eagerReducer: null, + eagerState: null, + next: null + }; + var pending = queue.pending; + null === pending + ? (suspenseConfig.next = suspenseConfig) + : ((suspenseConfig.next = pending.next), (pending.next = suspenseConfig)); + queue.pending = suspenseConfig; + pending = fiber.alternate; if ( fiber === currentlyRenderingFiber$1 || - (null !== alternate && alternate === currentlyRenderingFiber$1) + (null !== pending && pending === currentlyRenderingFiber$1) ) - if ( - ((didScheduleRenderPhaseUpdate = !0), - (fiber = { - expirationTime: renderExpirationTime$1, - suspenseConfig: null, - action: action, - eagerReducer: null, - eagerState: null, - next: null - }), - null === renderPhaseUpdates && (renderPhaseUpdates = new Map()), - (action = renderPhaseUpdates.get(queue)), - void 0 === action) - ) - renderPhaseUpdates.set(queue, fiber); - else { - for (queue = action; null !== queue.next; ) queue = queue.next; - queue.next = fiber; - } + (didScheduleRenderPhaseUpdate = !0), + (suspenseConfig.expirationTime = renderExpirationTime$1), + (currentlyRenderingFiber$1.expirationTime = renderExpirationTime$1); else { - var currentTime = requestCurrentTimeForUpdate(), - suspenseConfig = ReactCurrentBatchConfig.suspense; - currentTime = computeExpirationForFiber(currentTime, fiber, suspenseConfig); - suspenseConfig = { - expirationTime: currentTime, - suspenseConfig: suspenseConfig, - action: action, - eagerReducer: null, - eagerState: null, - next: null - }; - var pending = queue.pending; - null === pending - ? (suspenseConfig.next = suspenseConfig) - : ((suspenseConfig.next = pending.next), (pending.next = suspenseConfig)); - queue.pending = suspenseConfig; if ( 0 === fiber.expirationTime && - (null === alternate || 0 === alternate.expirationTime) && - ((alternate = queue.lastRenderedReducer), null !== alternate) + (null === pending || 0 === pending.expirationTime) && + ((pending = queue.lastRenderedReducer), null !== pending) ) try { var currentState = queue.lastRenderedState, - eagerState = alternate(currentState, action); - suspenseConfig.eagerReducer = alternate; + eagerState = pending(currentState, action); + suspenseConfig.eagerReducer = pending; suspenseConfig.eagerState = eagerState; - if (is$1(eagerState, currentState)) return; + if (objectIs(eagerState, currentState)) return; } catch (error) { } finally { } @@ -3661,36 +3669,11 @@ var ContextOnlyDispatcher = { useCallback: updateCallback, useContext: readContext, useEffect: updateEffect, - useImperativeHandle: function(ref, create, deps) { - deps = null !== deps && void 0 !== deps ? deps.concat([ref]) : null; - return updateEffectImpl( - 4, - 36, - imperativeHandleEffect.bind(null, create, ref), - deps - ); - }, - useLayoutEffect: function(create, deps) { - return updateEffectImpl(4, 36, create, deps); - }, - useMemo: function(nextCreate, deps) { - var hook = updateWorkInProgressHook(); - deps = void 0 === deps ? null : deps; - var prevState = hook.memoizedState; - if ( - null !== prevState && - null !== deps && - areHookInputsEqual(deps, prevState[1]) - ) - return prevState[0]; - nextCreate = nextCreate(); - hook.memoizedState = [nextCreate, deps]; - return nextCreate; - }, + useImperativeHandle: updateImperativeHandle, + useLayoutEffect: updateLayoutEffect, + useMemo: updateMemo, useReducer: updateReducer, - useRef: function() { - return updateWorkInProgressHook().memoizedState; - }, + useRef: updateRef, useState: updateState, useDebugValue: mountDebugValue, useResponder: createDeprecatedResponderListener, @@ -3726,6 +3709,51 @@ var ContextOnlyDispatcher = { ]; } }, + HooksDispatcherOnRerender = { + readContext: readContext, + useCallback: updateCallback, + useContext: readContext, + useEffect: updateEffect, + useImperativeHandle: updateImperativeHandle, + useLayoutEffect: updateLayoutEffect, + useMemo: updateMemo, + useReducer: rerenderReducer, + useRef: updateRef, + useState: rerenderState, + useDebugValue: mountDebugValue, + useResponder: createDeprecatedResponderListener, + useDeferredValue: function(value, config) { + var _rerenderState = rerenderState(value), + prevValue = _rerenderState[0], + setValue = _rerenderState[1]; + updateEffect( + function() { + var previousConfig = ReactCurrentBatchConfig$1.suspense; + ReactCurrentBatchConfig$1.suspense = + void 0 === config ? null : config; + try { + setValue(value); + } finally { + ReactCurrentBatchConfig$1.suspense = previousConfig; + } + }, + [value, config] + ); + return prevValue; + }, + useTransition: function(config) { + var _rerenderState2 = rerenderState(!1), + isPending = _rerenderState2[0]; + _rerenderState2 = _rerenderState2[1]; + return [ + updateCallback(startTransition.bind(null, _rerenderState2, config), [ + _rerenderState2, + config + ]), + isPending + ]; + } + }, now$1 = Scheduler.unstable_now, commitTime = 0, profilerStartTime = -1; @@ -5799,8 +5827,8 @@ function requestCurrentTimeForUpdate() { return (executionContext & (RenderContext | CommitContext)) !== NoContext ? 1073741821 - ((now() / 10) | 0) : 0 !== currentEventTime - ? currentEventTime - : (currentEventTime = 1073741821 - ((now() / 10) | 0)); + ? currentEventTime + : (currentEventTime = 1073741821 - ((now() / 10) | 0)); } function computeExpirationForFiber(currentTime, fiber, suspenseConfig) { fiber = fiber.mode; @@ -5910,9 +5938,10 @@ function getNextRootExpirationTimeToWorkOn(root) { if (0 !== lastExpiredTime) return lastExpiredTime; lastExpiredTime = root.firstPendingTime; if (!isRootSuspendedAtTime(root, lastExpiredTime)) return lastExpiredTime; - lastExpiredTime = root.lastPingedTime; + var lastPingedTime = root.lastPingedTime; root = root.nextKnownPendingLevel; - return lastExpiredTime > root ? lastExpiredTime : root; + root = lastPingedTime > root ? lastPingedTime : root; + return 2 >= root && lastExpiredTime !== root ? 0 : root; } function ensureRootIsScheduled(root) { if (0 !== root.lastExpiredTime) @@ -6088,35 +6117,34 @@ function performConcurrentWorkOnRoot(root, didTimeout) { 10 * (1073741821 - workInProgressRootLatestSuspenseTimeout) - now()) : 1073741823 === workInProgressRootLatestProcessedExpirationTime - ? (prevExecutionContext = 0) - : ((prevExecutionContext = - 10 * - (1073741821 - - workInProgressRootLatestProcessedExpirationTime) - - 5e3), - (prevDispatcher = now()), - (expirationTime = - 10 * (1073741821 - expirationTime) - prevDispatcher), - (prevExecutionContext = - prevDispatcher - prevExecutionContext), - 0 > prevExecutionContext && (prevExecutionContext = 0), - (prevExecutionContext = - (120 > prevExecutionContext - ? 120 - : 480 > prevExecutionContext - ? 480 - : 1080 > prevExecutionContext - ? 1080 - : 1920 > prevExecutionContext - ? 1920 - : 3e3 > prevExecutionContext - ? 3e3 - : 4320 > prevExecutionContext - ? 4320 - : 1960 * ceil(prevExecutionContext / 1960)) - - prevExecutionContext), - expirationTime < prevExecutionContext && - (prevExecutionContext = expirationTime)); + ? (prevExecutionContext = 0) + : ((prevExecutionContext = + 10 * + (1073741821 - + workInProgressRootLatestProcessedExpirationTime) - + 5e3), + (prevDispatcher = now()), + (expirationTime = + 10 * (1073741821 - expirationTime) - prevDispatcher), + (prevExecutionContext = prevDispatcher - prevExecutionContext), + 0 > prevExecutionContext && (prevExecutionContext = 0), + (prevExecutionContext = + (120 > prevExecutionContext + ? 120 + : 480 > prevExecutionContext + ? 480 + : 1080 > prevExecutionContext + ? 1080 + : 1920 > prevExecutionContext + ? 1920 + : 3e3 > prevExecutionContext + ? 3e3 + : 4320 > prevExecutionContext + ? 4320 + : 1960 * ceil(prevExecutionContext / 1960)) - + prevExecutionContext), + expirationTime < prevExecutionContext && + (prevExecutionContext = expirationTime)); if (10 < prevExecutionContext) { root.timeoutHandle = scheduleTimeout( commitRoot.bind(null, root), @@ -6275,7 +6303,20 @@ function handleError(root$jscomp$0, thrownValue) { do { try { resetContextDependencies(); - resetHooks(); + ReactCurrentDispatcher$1.current = ContextOnlyDispatcher; + if (didScheduleRenderPhaseUpdate) + for ( + var hook = currentlyRenderingFiber$1.memoizedState; + null !== hook; + + ) { + var queue = hook.queue; + null !== queue && (queue.pending = null); + hook = hook.next; + } + renderExpirationTime$1 = 0; + workInProgressHook = currentHook = currentlyRenderingFiber$1 = null; + didScheduleRenderPhaseUpdate = !1; if (null === workInProgress || null === workInProgress.return) return ( (workInProgressRootExitStatus = RootFatalErrored), @@ -6320,10 +6361,10 @@ function handleError(root$jscomp$0, thrownValue) { void 0 === props.fallback ? !1 : !0 !== props.unstable_avoidThisFallback - ? !0 - : hasInvisibleParentBoundary - ? !1 - : !0; + ? !0 + : hasInvisibleParentBoundary + ? !1 + : !0; } } if (JSCompiler_temp) { @@ -6914,8 +6955,6 @@ function pingSuspendedRoot(root, thenable, suspendedTime) { ((thenable = root.lastPingedTime), (0 !== thenable && thenable < suspendedTime) || ((root.lastPingedTime = suspendedTime), - root.finishedExpirationTime === suspendedTime && - ((root.finishedExpirationTime = 0), (root.finishedWork = null)), ensureRootIsScheduled(root), schedulePendingInteractions(root, suspendedTime))); } @@ -7058,7 +7097,8 @@ beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { void 0 === renderState.$$typeof ) { workInProgress.tag = 1; - resetHooks(); + workInProgress.memoizedState = null; + workInProgress.updateQueue = null; if (isContextProvider(updateExpirationTime)) { var hasContext = !0; pushContextProvider(workInProgress); @@ -7332,7 +7372,7 @@ beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { pushProvider(workInProgress, hasContext); if (null !== getDerivedStateFromProps) { var oldValue = getDerivedStateFromProps.value; - hasContext = is$1(oldValue, hasContext) + hasContext = objectIs(oldValue, hasContext) ? 0 : ("function" === typeof updateExpirationTime._calculateChangedBits ? updateExpirationTime._calculateChangedBits( @@ -7984,8 +8024,8 @@ function findNodeHandle(componentOrHandle) { return null == componentOrHandle ? componentOrHandle : componentOrHandle.canonical - ? componentOrHandle.canonical._nativeTag - : componentOrHandle._nativeTag; + ? componentOrHandle.canonical._nativeTag + : componentOrHandle._nativeTag; } batchedUpdatesImpl = function(fn, a) { var prevExecutionContext = executionContext; @@ -8108,8 +8148,8 @@ var roots = new Map(), return null == componentOrHandle ? componentOrHandle : componentOrHandle.canonical - ? componentOrHandle.canonical - : componentOrHandle; + ? componentOrHandle.canonical + : componentOrHandle; }, findNodeHandle: findNodeHandle, dispatchCommand: function(handle, command, args) { @@ -8295,7 +8335,7 @@ var roots = new Map(), throw Error("getInspectorDataForViewTag() is not available in production"); }, bundleType: 0, - version: "16.12.0-experimental-19f6fe170", + version: "16.12.0-experimental-241c4467e", rendererPackageName: "react-native-renderer" }); var ReactNativeRenderer$2 = { default: ReactNativeRenderer }, diff --git a/Libraries/Renderer/implementations/ReactNativeRenderer-profiling.js b/Libraries/Renderer/implementations/ReactNativeRenderer-profiling.js index 2d39130d44..2d564b5579 100644 --- a/Libraries/Renderer/implementations/ReactNativeRenderer-profiling.js +++ b/Libraries/Renderer/implementations/ReactNativeRenderer-profiling.js @@ -350,8 +350,8 @@ function SyntheticEvent( ((targetInst = dispatchConfig[propName]) ? (this[propName] = targetInst(nativeEvent)) : "target" === propName - ? (this.target = nativeEventTarget) - : (this[propName] = nativeEvent[propName])); + ? (this.target = nativeEventTarget) + : (this[propName] = nativeEvent[propName])); this.isDefaultPrevented = (null != nativeEvent.defaultPrevented ? nativeEvent.defaultPrevented : !1 === nativeEvent.returnValue) @@ -564,10 +564,10 @@ function accumulate(current, next) { return null == current ? next : Array.isArray(current) - ? current.concat(next) - : Array.isArray(next) - ? [current].concat(next) - : [current, next]; + ? current.concat(next) + : Array.isArray(next) + ? [current].concat(next) + : [current, next]; } var responderInst = null, trackedTouchCount = 0; @@ -669,10 +669,10 @@ var eventTypes = { var shouldSetEventType = isStartish(topLevelType) ? eventTypes.startShouldSetResponder : isMoveish(topLevelType) - ? eventTypes.moveShouldSetResponder - : "topSelectionChange" === topLevelType - ? eventTypes.selectionChangeShouldSetResponder - : eventTypes.scrollShouldSetResponder; + ? eventTypes.moveShouldSetResponder + : "topSelectionChange" === topLevelType + ? eventTypes.selectionChangeShouldSetResponder + : eventTypes.scrollShouldSetResponder; if (responderInst) b: { var JSCompiler_temp = responderInst; @@ -826,10 +826,10 @@ var eventTypes = { (shouldSetEventType = shouldSetEventType ? eventTypes.responderStart : JSCompiler_temp - ? eventTypes.responderMove - : targetInst - ? eventTypes.responderEnd - : null) + ? eventTypes.responderMove + : targetInst + ? eventTypes.responderEnd + : null) ) (shouldSetEventType = ResponderSyntheticEvent.getPooled( shouldSetEventType, @@ -892,8 +892,8 @@ var eventTypes = { (topLevelType = shouldSetEventType ? eventTypes.responderTerminate : topLevelType - ? eventTypes.responderRelease - : null) + ? eventTypes.responderRelease + : null) ) (nativeEvent = ResponderSyntheticEvent.getPooled( topLevelType, @@ -1366,8 +1366,8 @@ function diffNestedProperty( return nextProp ? addNestedProperty(updatePayload, nextProp, validAttributes) : prevProp - ? clearNestedProperty(updatePayload, prevProp, validAttributes) - : updatePayload; + ? clearNestedProperty(updatePayload, prevProp, validAttributes) + : updatePayload; if (!Array.isArray(prevProp) && !Array.isArray(nextProp)) return diffProperties(updatePayload, prevProp, nextProp, validAttributes); if (Array.isArray(prevProp) && Array.isArray(nextProp)) { @@ -1890,18 +1890,18 @@ function inferPriorityFromExpirationTime(currentTime, expirationTime) { return 0 >= currentTime ? 99 : 250 >= currentTime - ? 98 - : 5250 >= currentTime - ? 97 - : 95; + ? 98 + : 5250 >= currentTime + ? 97 + : 95; } function is(x, y) { return (x === y && (0 !== x || 1 / x === 1 / y)) || (x !== x && y !== y); } -var is$1 = "function" === typeof Object.is ? Object.is : is, +var objectIs = "function" === typeof Object.is ? Object.is : is, hasOwnProperty = Object.prototype.hasOwnProperty; function shallowEqual(objA, objB) { - if (is$1(objA, objB)) return !0; + if (objectIs(objA, objB)) return !0; if ( "object" !== typeof objA || null === objA || @@ -1915,7 +1915,7 @@ function shallowEqual(objA, objB) { for (keysB = 0; keysB < keysA.length; keysB++) if ( !hasOwnProperty.call(objB, keysA[keysB]) || - !is$1(objA[keysA[keysB]], objB[keysA[keysB]]) + !objectIs(objA[keysA[keysB]], objB[keysA[keysB]]) ) return !1; return !0; @@ -2267,8 +2267,8 @@ function checkShouldComponentUpdate( return "function" === typeof workInProgress.shouldComponentUpdate ? workInProgress.shouldComponentUpdate(newProps, newState, nextContext) : ctor.prototype && ctor.prototype.isPureReactComponent - ? !shallowEqual(oldProps, newProps) || !shallowEqual(oldState, newState) - : !0; + ? !shallowEqual(oldProps, newProps) || !shallowEqual(oldState, newState) + : !0; } function constructClassInstance(workInProgress, ctor, props) { var isLegacyContextConsumer = !1, @@ -3163,9 +3163,7 @@ var ReactCurrentDispatcher$1 = ReactSharedInternals.ReactCurrentDispatcher, currentlyRenderingFiber$1 = null, currentHook = null, workInProgressHook = null, - didScheduleRenderPhaseUpdate = !1, - renderPhaseUpdates = null, - numberOfReRenders = 0; + didScheduleRenderPhaseUpdate = !1; function throwInvalidHookError() { throw Error( "Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons:\n1. You might have mismatching versions of React and the renderer (such as React DOM)\n2. You might be breaking the Rules of Hooks\n3. You might have more than one copy of React in the same app\nSee https://fb.me/react-invalid-hook-call for tips about how to debug and fix this problem." @@ -3174,7 +3172,7 @@ function throwInvalidHookError() { function areHookInputsEqual(nextDeps, prevDeps) { if (null === prevDeps) return !1; for (var i = 0; i < prevDeps.length && i < nextDeps.length; i++) - if (!is$1(nextDeps[i], prevDeps[i])) return !1; + if (!objectIs(nextDeps[i], prevDeps[i])) return !1; return !0; } function renderWithHooks( @@ -3195,36 +3193,32 @@ function renderWithHooks( ? HooksDispatcherOnMount : HooksDispatcherOnUpdate; current = Component(props, secondArg); - if (didScheduleRenderPhaseUpdate) { - do - (didScheduleRenderPhaseUpdate = !1), - (numberOfReRenders += 1), - (workInProgressHook = currentHook = null), - (workInProgress.updateQueue = null), - (ReactCurrentDispatcher$1.current = HooksDispatcherOnUpdate), - (current = Component(props, secondArg)); - while (didScheduleRenderPhaseUpdate); - renderPhaseUpdates = null; - numberOfReRenders = 0; + if (workInProgress.expirationTime === renderExpirationTime$1) { + nextRenderExpirationTime = 0; + do { + workInProgress.expirationTime = 0; + if (!(25 > nextRenderExpirationTime)) + throw Error( + "Too many re-renders. React limits the number of renders to prevent an infinite loop." + ); + nextRenderExpirationTime += 1; + workInProgressHook = currentHook = null; + workInProgress.updateQueue = null; + ReactCurrentDispatcher$1.current = HooksDispatcherOnRerender; + current = Component(props, secondArg); + } while (workInProgress.expirationTime === renderExpirationTime$1); } ReactCurrentDispatcher$1.current = ContextOnlyDispatcher; workInProgress = null !== currentHook && null !== currentHook.next; renderExpirationTime$1 = 0; workInProgressHook = currentHook = currentlyRenderingFiber$1 = null; + didScheduleRenderPhaseUpdate = !1; if (workInProgress) throw Error( "Rendered fewer hooks than expected. This may be caused by an accidental early return statement." ); return current; } -function resetHooks() { - ReactCurrentDispatcher$1.current = ContextOnlyDispatcher; - renderExpirationTime$1 = 0; - workInProgressHook = currentHook = currentlyRenderingFiber$1 = null; - didScheduleRenderPhaseUpdate = !1; - renderPhaseUpdates = null; - numberOfReRenders = 0; -} function mountWorkInProgressHook() { var hook = { memoizedState: null, @@ -3279,57 +3273,36 @@ function updateReducer(reducer) { "Should have a queue. This is likely a bug in React. Please file an issue." ); queue.lastRenderedReducer = reducer; - if (0 < numberOfReRenders) { - var _dispatch = queue.dispatch; - if (null !== renderPhaseUpdates) { - var firstRenderPhaseUpdate = renderPhaseUpdates.get(queue); - if (void 0 !== firstRenderPhaseUpdate) { - renderPhaseUpdates.delete(queue); - var newState = hook.memoizedState; - do - (newState = reducer(newState, firstRenderPhaseUpdate.action)), - (firstRenderPhaseUpdate = firstRenderPhaseUpdate.next); - while (null !== firstRenderPhaseUpdate); - is$1(newState, hook.memoizedState) || (didReceiveUpdate = !0); - hook.memoizedState = newState; - null === hook.baseQueue && (hook.baseState = newState); - queue.lastRenderedState = newState; - return [newState, _dispatch]; - } + var current = currentHook, + baseQueue = current.baseQueue, + pendingQueue = queue.pending; + if (null !== pendingQueue) { + if (null !== baseQueue) { + var baseFirst = baseQueue.next; + baseQueue.next = pendingQueue.next; + pendingQueue.next = baseFirst; } - return [hook.memoizedState, _dispatch]; - } - newState = currentHook; - _dispatch = newState.baseQueue; - firstRenderPhaseUpdate = queue.pending; - if (null !== firstRenderPhaseUpdate) { - if (null !== _dispatch) { - var baseFirst = _dispatch.next; - _dispatch.next = firstRenderPhaseUpdate.next; - firstRenderPhaseUpdate.next = baseFirst; - } - newState.baseQueue = _dispatch = firstRenderPhaseUpdate; + current.baseQueue = baseQueue = pendingQueue; queue.pending = null; } - if (null !== _dispatch) { - _dispatch = _dispatch.next; - newState = newState.baseState; - var newBaseQueueLast = (baseFirst = firstRenderPhaseUpdate = null), - _update = _dispatch; + if (null !== baseQueue) { + baseQueue = baseQueue.next; + current = current.baseState; + var newBaseQueueLast = (baseFirst = pendingQueue = null), + update = baseQueue; do { - var updateExpirationTime = _update.expirationTime; + var updateExpirationTime = update.expirationTime; if (updateExpirationTime < renderExpirationTime$1) { var clone = { - expirationTime: _update.expirationTime, - suspenseConfig: _update.suspenseConfig, - action: _update.action, - eagerReducer: _update.eagerReducer, - eagerState: _update.eagerState, + expirationTime: update.expirationTime, + suspenseConfig: update.suspenseConfig, + action: update.action, + eagerReducer: update.eagerReducer, + eagerState: update.eagerState, next: null }; null === newBaseQueueLast - ? ((baseFirst = newBaseQueueLast = clone), - (firstRenderPhaseUpdate = newState)) + ? ((baseFirst = newBaseQueueLast = clone), (pendingQueue = current)) : (newBaseQueueLast = newBaseQueueLast.next = clone); updateExpirationTime > currentlyRenderingFiber$1.expirationTime && ((currentlyRenderingFiber$1.expirationTime = updateExpirationTime), @@ -3338,33 +3311,56 @@ function updateReducer(reducer) { null !== newBaseQueueLast && (newBaseQueueLast = newBaseQueueLast.next = { expirationTime: 1073741823, - suspenseConfig: _update.suspenseConfig, - action: _update.action, - eagerReducer: _update.eagerReducer, - eagerState: _update.eagerState, + suspenseConfig: update.suspenseConfig, + action: update.action, + eagerReducer: update.eagerReducer, + eagerState: update.eagerState, next: null }), markRenderEventTimeAndConfig( updateExpirationTime, - _update.suspenseConfig + update.suspenseConfig ), - (newState = - _update.eagerReducer === reducer - ? _update.eagerState - : reducer(newState, _update.action)); - _update = _update.next; - } while (null !== _update && _update !== _dispatch); + (current = + update.eagerReducer === reducer + ? update.eagerState + : reducer(current, update.action)); + update = update.next; + } while (null !== update && update !== baseQueue); null === newBaseQueueLast - ? (firstRenderPhaseUpdate = newState) + ? (pendingQueue = current) : (newBaseQueueLast.next = baseFirst); - is$1(newState, hook.memoizedState) || (didReceiveUpdate = !0); - hook.memoizedState = newState; - hook.baseState = firstRenderPhaseUpdate; + objectIs(current, hook.memoizedState) || (didReceiveUpdate = !0); + hook.memoizedState = current; + hook.baseState = pendingQueue; hook.baseQueue = newBaseQueueLast; - queue.lastRenderedState = newState; + queue.lastRenderedState = current; } return [hook.memoizedState, queue.dispatch]; } +function rerenderReducer(reducer) { + var hook = updateWorkInProgressHook(), + queue = hook.queue; + if (null === queue) + throw Error( + "Should have a queue. This is likely a bug in React. Please file an issue." + ); + queue.lastRenderedReducer = reducer; + var dispatch = queue.dispatch, + lastRenderPhaseUpdate = queue.pending, + newState = hook.memoizedState; + if (null !== lastRenderPhaseUpdate) { + queue.pending = null; + var update = (lastRenderPhaseUpdate = lastRenderPhaseUpdate.next); + do (newState = reducer(newState, update.action)), (update = update.next); + while (update !== lastRenderPhaseUpdate); + objectIs(newState, hook.memoizedState) || (didReceiveUpdate = !0); + hook.memoizedState = newState; + null === hook.baseQueue && (hook.baseState = newState); + queue.lastRenderedState = newState; + } + return [newState, dispatch]; +} function mountState(initialState) { var hook = mountWorkInProgressHook(); "function" === typeof initialState && (initialState = initialState()); @@ -3385,6 +3381,9 @@ function mountState(initialState) { function updateState(initialState) { return updateReducer(basicStateReducer, initialState); } +function rerenderState(initialState) { + return rerenderReducer(basicStateReducer, initialState); +} function pushEffect(tag, create, destroy, deps) { tag = { tag: tag, create: create, destroy: destroy, deps: deps, next: null }; create = currentlyRenderingFiber$1.updateQueue; @@ -3401,6 +3400,9 @@ function pushEffect(tag, create, destroy, deps) { (create.lastEffect = tag))); return tag; } +function updateRef() { + return updateWorkInProgressHook().memoizedState; +} function mountEffectImpl(fiberEffectTag, hookEffectTag, create, deps) { var hook = mountWorkInProgressHook(); currentlyRenderingFiber$1.effectTag |= fiberEffectTag; @@ -3432,6 +3434,9 @@ function mountEffect(create, deps) { function updateEffect(create, deps) { return updateEffectImpl(516, 192, create, deps); } +function updateLayoutEffect(create, deps) { + return updateEffectImpl(4, 36, create, deps); +} function imperativeHandleEffect(create, ref) { if ("function" === typeof ref) return ( @@ -3450,6 +3455,15 @@ function imperativeHandleEffect(create, ref) { } ); } +function updateImperativeHandle(ref, create, deps) { + deps = null !== deps && void 0 !== deps ? deps.concat([ref]) : null; + return updateEffectImpl( + 4, + 36, + imperativeHandleEffect.bind(null, create, ref), + deps + ); +} function mountDebugValue() {} function mountCallback(callback, deps) { mountWorkInProgressHook().memoizedState = [ @@ -3471,6 +3485,20 @@ function updateCallback(callback, deps) { hook.memoizedState = [callback, deps]; return callback; } +function updateMemo(nextCreate, deps) { + var hook = updateWorkInProgressHook(); + deps = void 0 === deps ? null : deps; + var prevState = hook.memoizedState; + if ( + null !== prevState && + null !== deps && + areHookInputsEqual(deps, prevState[1]) + ) + return prevState[0]; + nextCreate = nextCreate(); + hook.memoizedState = [nextCreate, deps]; + return nextCreate; +} function startTransition(setPending, config, callback) { var priorityLevel = getCurrentPriorityLevel(); runWithPriority(98 > priorityLevel ? 98 : priorityLevel, function() { @@ -3487,62 +3515,42 @@ function startTransition(setPending, config, callback) { }); } function dispatchAction(fiber, queue, action) { - if (!(25 > numberOfReRenders)) - throw Error( - "Too many re-renders. React limits the number of renders to prevent an infinite loop." - ); - var alternate = fiber.alternate; + var currentTime = requestCurrentTimeForUpdate(), + suspenseConfig = ReactCurrentBatchConfig.suspense; + currentTime = computeExpirationForFiber(currentTime, fiber, suspenseConfig); + suspenseConfig = { + expirationTime: currentTime, + suspenseConfig: suspenseConfig, + action: action, + eagerReducer: null, + eagerState: null, + next: null + }; + var pending = queue.pending; + null === pending + ? (suspenseConfig.next = suspenseConfig) + : ((suspenseConfig.next = pending.next), (pending.next = suspenseConfig)); + queue.pending = suspenseConfig; + pending = fiber.alternate; if ( fiber === currentlyRenderingFiber$1 || - (null !== alternate && alternate === currentlyRenderingFiber$1) + (null !== pending && pending === currentlyRenderingFiber$1) ) - if ( - ((didScheduleRenderPhaseUpdate = !0), - (fiber = { - expirationTime: renderExpirationTime$1, - suspenseConfig: null, - action: action, - eagerReducer: null, - eagerState: null, - next: null - }), - null === renderPhaseUpdates && (renderPhaseUpdates = new Map()), - (action = renderPhaseUpdates.get(queue)), - void 0 === action) - ) - renderPhaseUpdates.set(queue, fiber); - else { - for (queue = action; null !== queue.next; ) queue = queue.next; - queue.next = fiber; - } + (didScheduleRenderPhaseUpdate = !0), + (suspenseConfig.expirationTime = renderExpirationTime$1), + (currentlyRenderingFiber$1.expirationTime = renderExpirationTime$1); else { - var currentTime = requestCurrentTimeForUpdate(), - suspenseConfig = ReactCurrentBatchConfig.suspense; - currentTime = computeExpirationForFiber(currentTime, fiber, suspenseConfig); - suspenseConfig = { - expirationTime: currentTime, - suspenseConfig: suspenseConfig, - action: action, - eagerReducer: null, - eagerState: null, - next: null - }; - var pending = queue.pending; - null === pending - ? (suspenseConfig.next = suspenseConfig) - : ((suspenseConfig.next = pending.next), (pending.next = suspenseConfig)); - queue.pending = suspenseConfig; if ( 0 === fiber.expirationTime && - (null === alternate || 0 === alternate.expirationTime) && - ((alternate = queue.lastRenderedReducer), null !== alternate) + (null === pending || 0 === pending.expirationTime) && + ((pending = queue.lastRenderedReducer), null !== pending) ) try { var currentState = queue.lastRenderedState, - eagerState = alternate(currentState, action); - suspenseConfig.eagerReducer = alternate; + eagerState = pending(currentState, action); + suspenseConfig.eagerReducer = pending; suspenseConfig.eagerState = eagerState; - if (is$1(eagerState, currentState)) return; + if (objectIs(eagerState, currentState)) return; } catch (error) { } finally { } @@ -3651,36 +3659,11 @@ var ContextOnlyDispatcher = { useCallback: updateCallback, useContext: readContext, useEffect: updateEffect, - useImperativeHandle: function(ref, create, deps) { - deps = null !== deps && void 0 !== deps ? deps.concat([ref]) : null; - return updateEffectImpl( - 4, - 36, - imperativeHandleEffect.bind(null, create, ref), - deps - ); - }, - useLayoutEffect: function(create, deps) { - return updateEffectImpl(4, 36, create, deps); - }, - useMemo: function(nextCreate, deps) { - var hook = updateWorkInProgressHook(); - deps = void 0 === deps ? null : deps; - var prevState = hook.memoizedState; - if ( - null !== prevState && - null !== deps && - areHookInputsEqual(deps, prevState[1]) - ) - return prevState[0]; - nextCreate = nextCreate(); - hook.memoizedState = [nextCreate, deps]; - return nextCreate; - }, + useImperativeHandle: updateImperativeHandle, + useLayoutEffect: updateLayoutEffect, + useMemo: updateMemo, useReducer: updateReducer, - useRef: function() { - return updateWorkInProgressHook().memoizedState; - }, + useRef: updateRef, useState: updateState, useDebugValue: mountDebugValue, useResponder: createDeprecatedResponderListener, @@ -3716,6 +3699,51 @@ var ContextOnlyDispatcher = { ]; } }, + HooksDispatcherOnRerender = { + readContext: readContext, + useCallback: updateCallback, + useContext: readContext, + useEffect: updateEffect, + useImperativeHandle: updateImperativeHandle, + useLayoutEffect: updateLayoutEffect, + useMemo: updateMemo, + useReducer: rerenderReducer, + useRef: updateRef, + useState: rerenderState, + useDebugValue: mountDebugValue, + useResponder: createDeprecatedResponderListener, + useDeferredValue: function(value, config) { + var _rerenderState = rerenderState(value), + prevValue = _rerenderState[0], + setValue = _rerenderState[1]; + updateEffect( + function() { + var previousConfig = ReactCurrentBatchConfig$1.suspense; + ReactCurrentBatchConfig$1.suspense = + void 0 === config ? null : config; + try { + setValue(value); + } finally { + ReactCurrentBatchConfig$1.suspense = previousConfig; + } + }, + [value, config] + ); + return prevValue; + }, + useTransition: function(config) { + var _rerenderState2 = rerenderState(!1), + isPending = _rerenderState2[0]; + _rerenderState2 = _rerenderState2[1]; + return [ + updateCallback(startTransition.bind(null, _rerenderState2, config), [ + _rerenderState2, + config + ]), + isPending + ]; + } + }, now$1 = Scheduler.unstable_now, commitTime = 0, profilerStartTime = -1; @@ -5789,8 +5817,8 @@ function requestCurrentTimeForUpdate() { return (executionContext & (RenderContext | CommitContext)) !== NoContext ? 1073741821 - ((now() / 10) | 0) : 0 !== currentEventTime - ? currentEventTime - : (currentEventTime = 1073741821 - ((now() / 10) | 0)); + ? currentEventTime + : (currentEventTime = 1073741821 - ((now() / 10) | 0)); } function computeExpirationForFiber(currentTime, fiber, suspenseConfig) { fiber = fiber.mode; @@ -5900,9 +5928,10 @@ function getNextRootExpirationTimeToWorkOn(root) { if (0 !== lastExpiredTime) return lastExpiredTime; lastExpiredTime = root.firstPendingTime; if (!isRootSuspendedAtTime(root, lastExpiredTime)) return lastExpiredTime; - lastExpiredTime = root.lastPingedTime; + var lastPingedTime = root.lastPingedTime; root = root.nextKnownPendingLevel; - return lastExpiredTime > root ? lastExpiredTime : root; + root = lastPingedTime > root ? lastPingedTime : root; + return 2 >= root && lastExpiredTime !== root ? 0 : root; } function ensureRootIsScheduled(root) { if (0 !== root.lastExpiredTime) @@ -6078,35 +6107,34 @@ function performConcurrentWorkOnRoot(root, didTimeout) { 10 * (1073741821 - workInProgressRootLatestSuspenseTimeout) - now()) : 1073741823 === workInProgressRootLatestProcessedExpirationTime - ? (prevExecutionContext = 0) - : ((prevExecutionContext = - 10 * - (1073741821 - - workInProgressRootLatestProcessedExpirationTime) - - 5e3), - (prevDispatcher = now()), - (expirationTime = - 10 * (1073741821 - expirationTime) - prevDispatcher), - (prevExecutionContext = - prevDispatcher - prevExecutionContext), - 0 > prevExecutionContext && (prevExecutionContext = 0), - (prevExecutionContext = - (120 > prevExecutionContext - ? 120 - : 480 > prevExecutionContext - ? 480 - : 1080 > prevExecutionContext - ? 1080 - : 1920 > prevExecutionContext - ? 1920 - : 3e3 > prevExecutionContext - ? 3e3 - : 4320 > prevExecutionContext - ? 4320 - : 1960 * ceil(prevExecutionContext / 1960)) - - prevExecutionContext), - expirationTime < prevExecutionContext && - (prevExecutionContext = expirationTime)); + ? (prevExecutionContext = 0) + : ((prevExecutionContext = + 10 * + (1073741821 - + workInProgressRootLatestProcessedExpirationTime) - + 5e3), + (prevDispatcher = now()), + (expirationTime = + 10 * (1073741821 - expirationTime) - prevDispatcher), + (prevExecutionContext = prevDispatcher - prevExecutionContext), + 0 > prevExecutionContext && (prevExecutionContext = 0), + (prevExecutionContext = + (120 > prevExecutionContext + ? 120 + : 480 > prevExecutionContext + ? 480 + : 1080 > prevExecutionContext + ? 1080 + : 1920 > prevExecutionContext + ? 1920 + : 3e3 > prevExecutionContext + ? 3e3 + : 4320 > prevExecutionContext + ? 4320 + : 1960 * ceil(prevExecutionContext / 1960)) - + prevExecutionContext), + expirationTime < prevExecutionContext && + (prevExecutionContext = expirationTime)); if (10 < prevExecutionContext) { root.timeoutHandle = scheduleTimeout( commitRoot.bind(null, root), @@ -6265,7 +6293,20 @@ function handleError(root$jscomp$0, thrownValue) { do { try { resetContextDependencies(); - resetHooks(); + ReactCurrentDispatcher$1.current = ContextOnlyDispatcher; + if (didScheduleRenderPhaseUpdate) + for ( + var hook = currentlyRenderingFiber$1.memoizedState; + null !== hook; + + ) { + var queue = hook.queue; + null !== queue && (queue.pending = null); + hook = hook.next; + } + renderExpirationTime$1 = 0; + workInProgressHook = currentHook = currentlyRenderingFiber$1 = null; + didScheduleRenderPhaseUpdate = !1; if (null === workInProgress || null === workInProgress.return) return ( (workInProgressRootExitStatus = RootFatalErrored), @@ -6310,10 +6351,10 @@ function handleError(root$jscomp$0, thrownValue) { void 0 === props.fallback ? !1 : !0 !== props.unstable_avoidThisFallback - ? !0 - : hasInvisibleParentBoundary - ? !1 - : !0; + ? !0 + : hasInvisibleParentBoundary + ? !1 + : !0; } } if (JSCompiler_temp) { @@ -6904,8 +6945,6 @@ function pingSuspendedRoot(root, thenable, suspendedTime) { ((thenable = root.lastPingedTime), (0 !== thenable && thenable < suspendedTime) || ((root.lastPingedTime = suspendedTime), - root.finishedExpirationTime === suspendedTime && - ((root.finishedExpirationTime = 0), (root.finishedWork = null)), ensureRootIsScheduled(root), schedulePendingInteractions(root, suspendedTime))); } @@ -7048,7 +7087,8 @@ beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { void 0 === renderState.$$typeof ) { workInProgress.tag = 1; - resetHooks(); + workInProgress.memoizedState = null; + workInProgress.updateQueue = null; if (isContextProvider(updateExpirationTime)) { var hasContext = !0; pushContextProvider(workInProgress); @@ -7322,7 +7362,7 @@ beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { pushProvider(workInProgress, hasContext); if (null !== getDerivedStateFromProps) { var oldValue = getDerivedStateFromProps.value; - hasContext = is$1(oldValue, hasContext) + hasContext = objectIs(oldValue, hasContext) ? 0 : ("function" === typeof updateExpirationTime._calculateChangedBits ? updateExpirationTime._calculateChangedBits( @@ -7974,8 +8014,8 @@ function findNodeHandle(componentOrHandle) { return null == componentOrHandle ? componentOrHandle : componentOrHandle.canonical - ? componentOrHandle.canonical._nativeTag - : componentOrHandle._nativeTag; + ? componentOrHandle.canonical._nativeTag + : componentOrHandle._nativeTag; } batchedUpdatesImpl = function(fn, a) { var prevExecutionContext = executionContext; @@ -8098,8 +8138,8 @@ var roots = new Map(), return null == componentOrHandle ? componentOrHandle : componentOrHandle.canonical - ? componentOrHandle.canonical - : componentOrHandle; + ? componentOrHandle.canonical + : componentOrHandle; }, findNodeHandle: findNodeHandle, dispatchCommand: function(handle, command, args) { @@ -8285,7 +8325,7 @@ var roots = new Map(), throw Error("getInspectorDataForViewTag() is not available in production"); }, bundleType: 0, - version: "16.12.0-19f6fe170", + version: "16.12.0-241c4467e", rendererPackageName: "react-native-renderer" }); var ReactNativeRenderer$2 = { default: ReactNativeRenderer }, diff --git a/Libraries/Renderer/shims/ReactFabric.js b/Libraries/Renderer/shims/ReactFabric.js index 8f6a708fd2..536ce9a6f3 100644 --- a/Libraries/Renderer/shims/ReactFabric.js +++ b/Libraries/Renderer/shims/ReactFabric.js @@ -23,6 +23,10 @@ if (__DEV__) { ReactFabric = require('../implementations/ReactFabric-prod'); } -BatchedBridge.registerCallableModule('ReactFabric', ReactFabric); +if (global.RN$Bridgeless) { + global.RN$stopSurface = ReactFabric.stopSurface; +} else { + BatchedBridge.registerCallableModule('ReactFabric', ReactFabric); +} module.exports = (ReactFabric: ReactNativeType); diff --git a/Libraries/Renderer/shims/ReactNativeViewConfigRegistry.js b/Libraries/Renderer/shims/ReactNativeViewConfigRegistry.js index e6e3b13b8e..2c09ddf3ca 100644 --- a/Libraries/Renderer/shims/ReactNativeViewConfigRegistry.js +++ b/Libraries/Renderer/shims/ReactNativeViewConfigRegistry.js @@ -8,7 +8,7 @@ * @flow strict-local */ -/* eslint-disable react-internal/warning-and-invariant-args */ +/* eslint-disable react-internal/invariant-args */ 'use strict'; diff --git a/Libraries/Renderer/shims/ReactTypes.js b/Libraries/Renderer/shims/ReactTypes.js index e97e582339..74c255577d 100644 --- a/Libraries/Renderer/shims/ReactTypes.js +++ b/Libraries/Renderer/shims/ReactTypes.js @@ -170,18 +170,17 @@ export type ReactScope = {| $$typeof: Symbol | number, |}; +export type ReactScopeQuery = ( + type: string, + props: {[string]: mixed, ...}, + instance: mixed, +) => boolean; + export type ReactScopeMethods = {| - getChildren(): null | Array, - getChildrenFromRoot(): null | Array, - getParent(): null | ReactScopeMethods, - getProps(): Object, - queryAllNodes( - (type: string | Object, props: Object, instance: Object) => boolean, - ): null | Array, - queryFirstNode( - (type: string | Object, props: Object, instance: Object) => boolean, - ): null | Object, + DO_NOT_USE_queryAllNodes(ReactScopeQuery): null | Array, + DO_NOT_USE_queryFirstNode(ReactScopeQuery): null | Object, containsNode(Object): boolean, + getChildContextValues: (context: ReactContext) => Array, |}; export type ReactScopeInstance = {|