How to use mountHookTypesDev method in Playwright Internal

Best JavaScript code snippet using playwright-internal

ReactFiberHooks.old.js

Source:ReactFiberHooks.old.js Github

copy

Full Screen

...31 var hookTypesUpdateIndexDev = -1; // In DEV, this tracks whether currently rendering component needs to ignore32 // the dependencies for Hooks that need them (e.g. useEffect or useMemo).33 // When true, such Hooks will always be "remounted". Only used during hot reload.34 var ignorePreviousDependencies = false;35 function mountHookTypesDev() {36 {37 var hookName = currentHookNameInDev;38 if (hookTypesDev === null) {39 hookTypesDev = [hookName];40 } else {41 hookTypesDev.push(hookName);42 }43 }44 }45 function updateHookTypesDev() {46 {47 var hookName = currentHookNameInDev;48 if (hookTypesDev !== null) {49 hookTypesUpdateIndexDev++;50 if (hookTypesDev[hookTypesUpdateIndexDev] !== hookName) {51 warnOnHookMismatchInDev(hookName);52 }53 }54 }55 }56 function checkDepsAreArrayDev(deps) {57 {58 if (deps !== undefined && deps !== null && !Array.isArray(deps)) {59 // Verify deps, but only on mount to avoid extra checks.60 // It's unlikely their type would change as usually you define them inline.61 error('%s received a final argument that is not an array (instead, received `%s`). When ' + 'specified, the final argument must be an array.', currentHookNameInDev, typeof deps);62 }63 }64 }65 function warnOnHookMismatchInDev(currentHookName) {66 {67 var componentName = getComponentName(currentlyRenderingFiber$1.type);68 if (!didWarnAboutMismatchedHooksForComponent.has(componentName)) {69 didWarnAboutMismatchedHooksForComponent.add(componentName);70 if (hookTypesDev !== null) {71 var table = '';72 var secondColumnStart = 30;73 for (var i = 0; i <= hookTypesUpdateIndexDev; i++) {74 var oldHookName = hookTypesDev[i];75 var newHookName = i === hookTypesUpdateIndexDev ? currentHookName : oldHookName;76 var row = i + 1 + ". " + oldHookName; // Extra space so second column lines up77 // lol @ IE not supporting String#repeat78 while (row.length < secondColumnStart) {79 row += ' ';80 }81 row += newHookName + '\n';82 table += row;83 }84 error('React has detected a change in the order of Hooks called by %s. ' + 'This will lead to bugs and errors if not fixed. ' + 'For more information, read the Rules of Hooks: https://reactjs.org/link/rules-of-hooks\n\n' + ' Previous render Next render\n' + ' ------------------------------------------------------\n' + '%s' + ' ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n', componentName, table);85 }86 }87 }88 }89 function throwInvalidHookError() {90 {91 {92 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://reactjs.org/link/invalid-hook-call for tips about how to debug and fix this problem." );93 }94 }95 }96 function areHookInputsEqual(nextDeps, prevDeps) {97 {98 if (ignorePreviousDependencies) {99 // Only true when this component is being hot reloaded.100 return false;101 }102 }103 if (prevDeps === null) {104 {105 error('%s received a final argument during this render, but not during ' + 'the previous render. Even though the final argument is optional, ' + 'its type cannot change between renders.', currentHookNameInDev);106 }107 return false;108 }109 {110 // Don't bother comparing lengths in prod because these arrays should be111 // passed inline.112 if (nextDeps.length !== prevDeps.length) {113 error('The final argument passed to %s changed size between renders. The ' + 'order and size of this array must remain constant.\n\n' + 'Previous: %s\n' + 'Incoming: %s', currentHookNameInDev, "[" + prevDeps.join(', ') + "]", "[" + nextDeps.join(', ') + "]");114 }115 }116 for (var i = 0; i < prevDeps.length && i < nextDeps.length; i++) {117 if (objectIs(nextDeps[i], prevDeps[i])) {118 continue;119 }120 return false;121 }122 return true;123 }124 function renderWithHooks(current, workInProgress, Component, props, secondArg, nextRenderLanes) {125 renderLanes = nextRenderLanes;126 currentlyRenderingFiber$1 = workInProgress;127 {128 hookTypesDev = current !== null ? current._debugHookTypes : null;129 hookTypesUpdateIndexDev = -1; // Used for hot reloading:130 ignorePreviousDependencies = current !== null && current.type !== workInProgress.type;131 }132 workInProgress.memoizedState = null;133 workInProgress.updateQueue = null;134 workInProgress.lanes = NoLanes; // The following should have already been reset135 // currentHook = null;136 // workInProgressHook = null;137 // didScheduleRenderPhaseUpdate = false;138 // TODO Warn if no hooks are used at all during mount, then some are used during update.139 // Currently we will identify the update render as a mount because memoizedState === null.140 // This is tricky because it's valid for certain types of components (e.g. React.lazy)141 // Using memoizedState to differentiate between mount/update only works if at least one stateful hook is used.142 // Non-stateful hooks (e.g. context) don't get added to memoizedState,143 // so memoizedState would be null during updates and mounts.144 {145 if (current !== null && current.memoizedState !== null) {146 ReactCurrentDispatcher$1.current = HooksDispatcherOnUpdateInDEV;147 } else if (hookTypesDev !== null) {148 // This dispatcher handles an edge case where a component is updating,149 // but no stateful hooks have been used.150 // We want to match the production code behavior (which will use HooksDispatcherOnMount),151 // but with the extra DEV validation to ensure hooks ordering hasn't changed.152 // This dispatcher does that.153 ReactCurrentDispatcher$1.current = HooksDispatcherOnMountWithHookTypesInDEV;154 } else {155 ReactCurrentDispatcher$1.current = HooksDispatcherOnMountInDEV;156 }157 }158 var children = Component(props, secondArg); // Check if there was a render phase update159 if (didScheduleRenderPhaseUpdateDuringThisPass) {160 // Keep rendering in a loop for as long as render phase updates continue to161 // be scheduled. Use a counter to prevent infinite loops.162 var numberOfReRenders = 0;163 do {164 didScheduleRenderPhaseUpdateDuringThisPass = false;165 if (!(numberOfReRenders < RE_RENDER_LIMIT)) {166 {167 throw Error( "Too many re-renders. React limits the number of renders to prevent an infinite loop." );168 }169 }170 numberOfReRenders += 1;171 {172 // Even when hot reloading, allow dependencies to stabilize173 // after first render to prevent infinite render phase updates.174 ignorePreviousDependencies = false;175 } // Start over from the beginning of the list176 currentHook = null;177 workInProgressHook = null;178 workInProgress.updateQueue = null;179 {180 // Also validate hook order for cascading updates.181 hookTypesUpdateIndexDev = -1;182 }183 ReactCurrentDispatcher$1.current = HooksDispatcherOnRerenderInDEV ;184 children = Component(props, secondArg);185 } while (didScheduleRenderPhaseUpdateDuringThisPass);186 } // We can assume the previous dispatcher is always this one, since we set it187 // at the beginning of the render phase and there's no re-entrancy.188 ReactCurrentDispatcher$1.current = ContextOnlyDispatcher;189 {190 workInProgress._debugHookTypes = hookTypesDev;191 } // This check uses currentHook so that it works the same in DEV and prod bundles.192 // hookTypesDev could catch more cases (e.g. context) but only in DEV bundles.193 var didRenderTooFewHooks = currentHook !== null && currentHook.next !== null;194 renderLanes = NoLanes;195 currentlyRenderingFiber$1 = null;196 currentHook = null;197 workInProgressHook = null;198 {199 currentHookNameInDev = null;200 hookTypesDev = null;201 hookTypesUpdateIndexDev = -1;202 }203 didScheduleRenderPhaseUpdate = false;204 if (!!didRenderTooFewHooks) {205 {206 throw Error( "Rendered fewer hooks than expected. This may be caused by an accidental early return statement." );207 }208 }209 return children;210 }211 function bailoutHooks(current, workInProgress, lanes) {212 workInProgress.updateQueue = current.updateQueue;213 workInProgress.flags &= ~(Passive | Update);214 current.lanes = removeLanes(current.lanes, lanes);215 }216 function resetHooksAfterThrow() {217 // We can assume the previous dispatcher is always this one, since we set it218 // at the beginning of the render phase and there's no re-entrancy.219 ReactCurrentDispatcher$1.current = ContextOnlyDispatcher;220 if (didScheduleRenderPhaseUpdate) {221 // There were render phase updates. These are only valid for this render222 // phase, which we are now aborting. Remove the updates from the queues so223 // they do not persist to the next render. Do not remove updates from hooks224 // that weren't processed.225 //226 // Only reset the updates from the queue if it has a clone. If it does227 // not have a clone, that means it wasn't processed, and the updates were228 // scheduled before we entered the render phase.229 var hook = currentlyRenderingFiber$1.memoizedState;230 while (hook !== null) {231 var queue = hook.queue;232 if (queue !== null) {233 queue.pending = null;234 }235 hook = hook.next;236 }237 didScheduleRenderPhaseUpdate = false;238 }239 renderLanes = NoLanes;240 currentlyRenderingFiber$1 = null;241 currentHook = null;242 workInProgressHook = null;243 {244 hookTypesDev = null;245 hookTypesUpdateIndexDev = -1;246 currentHookNameInDev = null;247 isUpdatingOpaqueValueInRenderPhase = false;248 }249 didScheduleRenderPhaseUpdateDuringThisPass = false;250 }251 function mountWorkInProgressHook() {252 var hook = {253 memoizedState: null,254 baseState: null,255 baseQueue: null,256 queue: null,257 next: null258 };259 if (workInProgressHook === null) {260 // This is the first hook in the list261 currentlyRenderingFiber$1.memoizedState = workInProgressHook = hook;262 } else {263 // Append to the end of the list264 workInProgressHook = workInProgressHook.next = hook;265 }266 return workInProgressHook;267 }268 function updateWorkInProgressHook() {269 // This function is used both for updates and for re-renders triggered by a270 // render phase update. It assumes there is either a current hook we can271 // clone, or a work-in-progress hook from a previous render pass that we can272 // use as a base. When we reach the end of the base list, we must switch to273 // the dispatcher used for mounts.274 var nextCurrentHook;275 if (currentHook === null) {276 var current = currentlyRenderingFiber$1.alternate;277 if (current !== null) {278 nextCurrentHook = current.memoizedState;279 } else {280 nextCurrentHook = null;281 }282 } else {283 nextCurrentHook = currentHook.next;284 }285 var nextWorkInProgressHook;286 if (workInProgressHook === null) {287 nextWorkInProgressHook = currentlyRenderingFiber$1.memoizedState;288 } else {289 nextWorkInProgressHook = workInProgressHook.next;290 }291 if (nextWorkInProgressHook !== null) {292 // There's already a work-in-progress. Reuse it.293 workInProgressHook = nextWorkInProgressHook;294 nextWorkInProgressHook = workInProgressHook.next;295 currentHook = nextCurrentHook;296 } else {297 // Clone from the current hook.298 if (!(nextCurrentHook !== null)) {299 {300 throw Error( "Rendered more hooks than during the previous render." );301 }302 }303 currentHook = nextCurrentHook;304 var newHook = {305 memoizedState: currentHook.memoizedState,306 baseState: currentHook.baseState,307 baseQueue: currentHook.baseQueue,308 queue: currentHook.queue,309 next: null310 };311 if (workInProgressHook === null) {312 // This is the first hook in the list.313 currentlyRenderingFiber$1.memoizedState = workInProgressHook = newHook;314 } else {315 // Append to the end of the list.316 workInProgressHook = workInProgressHook.next = newHook;317 }318 }319 return workInProgressHook;320 }321 function createFunctionComponentUpdateQueue() {322 return {323 lastEffect: null324 };325 }326 function basicStateReducer(state, action) {327 // $FlowFixMe: Flow doesn't like mixed types328 return typeof action === 'function' ? action(state) : action;329 }330 function mountReducer(reducer, initialArg, init) {331 var hook = mountWorkInProgressHook();332 var initialState;333 if (init !== undefined) {334 initialState = init(initialArg);335 } else {336 initialState = initialArg;337 }338 hook.memoizedState = hook.baseState = initialState;339 var queue = hook.queue = {340 pending: null,341 dispatch: null,342 lastRenderedReducer: reducer,343 lastRenderedState: initialState344 };345 var dispatch = queue.dispatch = dispatchAction.bind(null, currentlyRenderingFiber$1, queue);346 return [hook.memoizedState, dispatch];347 }348 function updateReducer(reducer, initialArg, init) {349 var hook = updateWorkInProgressHook();350 var queue = hook.queue;351 if (!(queue !== null)) {352 {353 throw Error( "Should have a queue. This is likely a bug in React. Please file an issue." );354 }355 }356 queue.lastRenderedReducer = reducer;357 var current = currentHook; // The last rebase update that is NOT part of the base state.358 var baseQueue = current.baseQueue; // The last pending update that hasn't been processed yet.359 var pendingQueue = queue.pending;360 if (pendingQueue !== null) {361 // We have new updates that haven't been processed yet.362 // We'll add them to the base queue.363 if (baseQueue !== null) {364 // Merge the pending queue and the base queue.365 var baseFirst = baseQueue.next;366 var pendingFirst = pendingQueue.next;367 baseQueue.next = pendingFirst;368 pendingQueue.next = baseFirst;369 }370 {371 if (current.baseQueue !== baseQueue) {372 // Internal invariant that should never happen, but feasibly could in373 // the future if we implement resuming, or some form of that.374 error('Internal error: Expected work-in-progress queue to be a clone. ' + 'This is a bug in React.');375 }376 }377 current.baseQueue = baseQueue = pendingQueue;378 queue.pending = null;379 }380 if (baseQueue !== null) {381 // We have a queue to process.382 var first = baseQueue.next;383 var newState = current.baseState;384 var newBaseState = null;385 var newBaseQueueFirst = null;386 var newBaseQueueLast = null;387 var update = first;388 do {389 var updateLane = update.lane;390 if (!isSubsetOfLanes(renderLanes, updateLane)) {391 // Priority is insufficient. Skip this update. If this is the first392 // skipped update, the previous update/state is the new base393 // update/state.394 var clone = {395 lane: updateLane,396 action: update.action,397 eagerReducer: update.eagerReducer,398 eagerState: update.eagerState,399 next: null400 };401 if (newBaseQueueLast === null) {402 newBaseQueueFirst = newBaseQueueLast = clone;403 newBaseState = newState;404 } else {405 newBaseQueueLast = newBaseQueueLast.next = clone;406 } // Update the remaining priority in the queue.407 // TODO: Don't need to accumulate this. Instead, we can remove408 // renderLanes from the original lanes.409 currentlyRenderingFiber$1.lanes = mergeLanes(currentlyRenderingFiber$1.lanes, updateLane);410 markSkippedUpdateLanes(updateLane);411 } else {412 // This update does have sufficient priority.413 if (newBaseQueueLast !== null) {414 var _clone = {415 // This update is going to be committed so we never want uncommit416 // it. Using NoLane works because 0 is a subset of all bitmasks, so417 // this will never be skipped by the check above.418 lane: NoLane,419 action: update.action,420 eagerReducer: update.eagerReducer,421 eagerState: update.eagerState,422 next: null423 };424 newBaseQueueLast = newBaseQueueLast.next = _clone;425 } // Process this update.426 if (update.eagerReducer === reducer) {427 // If this update was processed eagerly, and its reducer matches the428 // current reducer, we can use the eagerly computed state.429 newState = update.eagerState;430 } else {431 var action = update.action;432 newState = reducer(newState, action);433 }434 }435 update = update.next;436 } while (update !== null && update !== first);437 if (newBaseQueueLast === null) {438 newBaseState = newState;439 } else {440 newBaseQueueLast.next = newBaseQueueFirst;441 } // Mark that the fiber performed work, but only if the new state is442 // different from the current state.443 if (!objectIs(newState, hook.memoizedState)) {444 markWorkInProgressReceivedUpdate();445 }446 hook.memoizedState = newState;447 hook.baseState = newBaseState;448 hook.baseQueue = newBaseQueueLast;449 queue.lastRenderedState = newState;450 }451 var dispatch = queue.dispatch;452 return [hook.memoizedState, dispatch];453 }454 function rerenderReducer(reducer, initialArg, init) {455 var hook = updateWorkInProgressHook();456 var queue = hook.queue;457 if (!(queue !== null)) {458 {459 throw Error( "Should have a queue. This is likely a bug in React. Please file an issue." );460 }461 }462 queue.lastRenderedReducer = reducer; // This is a re-render. Apply the new render phase updates to the previous463 // work-in-progress hook.464 var dispatch = queue.dispatch;465 var lastRenderPhaseUpdate = queue.pending;466 var newState = hook.memoizedState;467 if (lastRenderPhaseUpdate !== null) {468 // The queue doesn't persist past this render pass.469 queue.pending = null;470 var firstRenderPhaseUpdate = lastRenderPhaseUpdate.next;471 var update = firstRenderPhaseUpdate;472 do {473 // Process this render phase update. We don't have to check the474 // priority because it will always be the same as the current475 // render's.476 var action = update.action;477 newState = reducer(newState, action);478 update = update.next;479 } while (update !== firstRenderPhaseUpdate); // Mark that the fiber performed work, but only if the new state is480 // different from the current state.481 if (!objectIs(newState, hook.memoizedState)) {482 markWorkInProgressReceivedUpdate();483 }484 hook.memoizedState = newState; // Don't persist the state accumulated from the render phase updates to485 // the base state unless the queue is empty.486 // TODO: Not sure if this is the desired semantics, but it's what we487 // do for gDSFP. I can't remember why.488 if (hook.baseQueue === null) {489 hook.baseState = newState;490 }491 queue.lastRenderedState = newState;492 }493 return [newState, dispatch];494 }495 function readFromUnsubcribedMutableSource(root, source, getSnapshot) {496 {497 warnAboutMultipleRenderersDEV(source);498 }499 var getVersion = source._getVersion;500 var version = getVersion(source._source); // Is it safe for this component to read from this source during the current render?501 var isSafeToReadFromSource = false; // Check the version first.502 // If this render has already been started with a specific version,503 // we can use it alone to determine if we can safely read from the source.504 var currentRenderVersion = getWorkInProgressVersion(source);505 if (currentRenderVersion !== null) {506 // It's safe to read if the store hasn't been mutated since the last time507 // we read something.508 isSafeToReadFromSource = currentRenderVersion === version;509 } else {510 // If there's no version, then this is the first time we've read from the511 // source during the current render pass, so we need to do a bit more work.512 // What we need to determine is if there are any hooks that already513 // subscribed to the source, and if so, whether there are any pending514 // mutations that haven't been synchronized yet.515 //516 // If there are no pending mutations, then `root.mutableReadLanes` will be517 // empty, and we know we can safely read.518 //519 // If there *are* pending mutations, we may still be able to safely read520 // if the currently rendering lanes are inclusive of the pending mutation521 // lanes, since that guarantees that the value we're about to read from522 // the source is consistent with the values that we read during the most523 // recent mutation.524 isSafeToReadFromSource = isSubsetOfLanes(renderLanes, root.mutableReadLanes);525 if (isSafeToReadFromSource) {526 // If it's safe to read from this source during the current render,527 // store the version in case other components read from it.528 // A changed version number will let those components know to throw and restart the render.529 setWorkInProgressVersion(source, version);530 }531 }532 if (isSafeToReadFromSource) {533 var snapshot = getSnapshot(source._source);534 {535 if (typeof snapshot === 'function') {536 error('Mutable source should not return a function as the snapshot value. ' + 'Functions may close over mutable values and cause tearing.');537 }538 }539 return snapshot;540 } else {541 // This handles the special case of a mutable source being shared between renderers.542 // In that case, if the source is mutated between the first and second renderer,543 // The second renderer don't know that it needs to reset the WIP version during unwind,544 // (because the hook only marks sources as dirty if it's written to their WIP version).545 // That would cause this tear check to throw again and eventually be visible to the user.546 // We can avoid this infinite loop by explicitly marking the source as dirty.547 //548 // This can lead to tearing in the first renderer when it resumes,549 // but there's nothing we can do about that (short of throwing here and refusing to continue the render).550 markSourceAsDirty(source);551 {552 {553 throw Error( "Cannot read from mutable source during the current render without tearing. This is a bug in React. Please file an issue." );554 }555 }556 }557 }558 function useMutableSource(hook, source, getSnapshot, subscribe) {559 var root = getWorkInProgressRoot();560 if (!(root !== null)) {561 {562 throw Error( "Expected a work-in-progress root. This is a bug in React. Please file an issue." );563 }564 }565 var getVersion = source._getVersion;566 var version = getVersion(source._source);567 var dispatcher = ReactCurrentDispatcher$1.current; // eslint-disable-next-line prefer-const568 var _dispatcher$useState = dispatcher.useState(function () {569 return readFromUnsubcribedMutableSource(root, source, getSnapshot);570 }),571 currentSnapshot = _dispatcher$useState[0],572 setSnapshot = _dispatcher$useState[1];573 var snapshot = currentSnapshot; // Grab a handle to the state hook as well.574 // We use it to clear the pending update queue if we have a new source.575 var stateHook = workInProgressHook;576 var memoizedState = hook.memoizedState;577 var refs = memoizedState.refs;578 var prevGetSnapshot = refs.getSnapshot;579 var prevSource = memoizedState.source;580 var prevSubscribe = memoizedState.subscribe;581 var fiber = currentlyRenderingFiber$1;582 hook.memoizedState = {583 refs: refs,584 source: source,585 subscribe: subscribe586 }; // Sync the values needed by our subscription handler after each commit.587 dispatcher.useEffect(function () {588 refs.getSnapshot = getSnapshot; // Normally the dispatch function for a state hook never changes,589 // but this hook recreates the queue in certain cases to avoid updates from stale sources.590 // handleChange() below needs to reference the dispatch function without re-subscribing,591 // so we use a ref to ensure that it always has the latest version.592 refs.setSnapshot = setSnapshot; // Check for a possible change between when we last rendered now.593 var maybeNewVersion = getVersion(source._source);594 if (!objectIs(version, maybeNewVersion)) {595 var maybeNewSnapshot = getSnapshot(source._source);596 {597 if (typeof maybeNewSnapshot === 'function') {598 error('Mutable source should not return a function as the snapshot value. ' + 'Functions may close over mutable values and cause tearing.');599 }600 }601 if (!objectIs(snapshot, maybeNewSnapshot)) {602 setSnapshot(maybeNewSnapshot);603 var lane = requestUpdateLane(fiber);604 markRootMutableRead(root, lane);605 } // If the source mutated between render and now,606 // there may be state updates already scheduled from the old source.607 // Entangle the updates so that they render in the same batch.608 markRootEntangled(root, root.mutableReadLanes);609 }610 }, [getSnapshot, source, subscribe]); // If we got a new source or subscribe function, re-subscribe in a passive effect.611 dispatcher.useEffect(function () {612 var handleChange = function () {613 var latestGetSnapshot = refs.getSnapshot;614 var latestSetSnapshot = refs.setSnapshot;615 try {616 latestSetSnapshot(latestGetSnapshot(source._source)); // Record a pending mutable source update with the same expiration time.617 var lane = requestUpdateLane(fiber);618 markRootMutableRead(root, lane);619 } catch (error) {620 // A selector might throw after a source mutation.621 // e.g. it might try to read from a part of the store that no longer exists.622 // In this case we should still schedule an update with React.623 // Worst case the selector will throw again and then an error boundary will handle it.624 latestSetSnapshot(function () {625 throw error;626 });627 }628 };629 var unsubscribe = subscribe(source._source, handleChange);630 {631 if (typeof unsubscribe !== 'function') {632 error('Mutable source subscribe function must return an unsubscribe function.');633 }634 }635 return unsubscribe;636 }, [source, subscribe]); // If any of the inputs to useMutableSource change, reading is potentially unsafe.637 //638 // If either the source or the subscription have changed we can't can't trust the update queue.639 // Maybe the source changed in a way that the old subscription ignored but the new one depends on.640 //641 // If the getSnapshot function changed, we also shouldn't rely on the update queue.642 // It's possible that the underlying source was mutated between the when the last "change" event fired,643 // and when the current render (with the new getSnapshot function) is processed.644 //645 // In both cases, we need to throw away pending updates (since they are no longer relevant)646 // and treat reading from the source as we do in the mount case.647 if (!objectIs(prevGetSnapshot, getSnapshot) || !objectIs(prevSource, source) || !objectIs(prevSubscribe, subscribe)) {648 // Create a new queue and setState method,649 // So if there are interleaved updates, they get pushed to the older queue.650 // When this becomes current, the previous queue and dispatch method will be discarded,651 // including any interleaving updates that occur.652 var newQueue = {653 pending: null,654 dispatch: null,655 lastRenderedReducer: basicStateReducer,656 lastRenderedState: snapshot657 };658 newQueue.dispatch = setSnapshot = dispatchAction.bind(null, currentlyRenderingFiber$1, newQueue);659 stateHook.queue = newQueue;660 stateHook.baseQueue = null;661 snapshot = readFromUnsubcribedMutableSource(root, source, getSnapshot);662 stateHook.memoizedState = stateHook.baseState = snapshot;663 }664 return snapshot;665 }666 function mountMutableSource(source, getSnapshot, subscribe) {667 var hook = mountWorkInProgressHook();668 hook.memoizedState = {669 refs: {670 getSnapshot: getSnapshot,671 setSnapshot: null672 },673 source: source,674 subscribe: subscribe675 };676 return useMutableSource(hook, source, getSnapshot, subscribe);677 }678 function updateMutableSource(source, getSnapshot, subscribe) {679 var hook = updateWorkInProgressHook();680 return useMutableSource(hook, source, getSnapshot, subscribe);681 }682 function mountState(initialState) {683 var hook = mountWorkInProgressHook();684 if (typeof initialState === 'function') {685 // $FlowFixMe: Flow doesn't like mixed types686 initialState = initialState();687 }688 hook.memoizedState = hook.baseState = initialState;689 var queue = hook.queue = {690 pending: null,691 dispatch: null,692 lastRenderedReducer: basicStateReducer,693 lastRenderedState: initialState694 };695 var dispatch = queue.dispatch = dispatchAction.bind(null, currentlyRenderingFiber$1, queue);696 return [hook.memoizedState, dispatch];697 }698 function updateState(initialState) {699 return updateReducer(basicStateReducer);700 }701 function rerenderState(initialState) {702 return rerenderReducer(basicStateReducer);703 }704 function pushEffect(tag, create, destroy, deps) {705 var effect = {706 tag: tag,707 create: create,708 destroy: destroy,709 deps: deps,710 // Circular711 next: null712 };713 var componentUpdateQueue = currentlyRenderingFiber$1.updateQueue;714 if (componentUpdateQueue === null) {715 componentUpdateQueue = createFunctionComponentUpdateQueue();716 currentlyRenderingFiber$1.updateQueue = componentUpdateQueue;717 componentUpdateQueue.lastEffect = effect.next = effect;718 } else {719 var lastEffect = componentUpdateQueue.lastEffect;720 if (lastEffect === null) {721 componentUpdateQueue.lastEffect = effect.next = effect;722 } else {723 var firstEffect = lastEffect.next;724 lastEffect.next = effect;725 effect.next = firstEffect;726 componentUpdateQueue.lastEffect = effect;727 }728 }729 return effect;730 }731 function mountRef(initialValue) {732 var hook = mountWorkInProgressHook();733 var ref = {734 current: initialValue735 };736 {737 Object.seal(ref);738 }739 hook.memoizedState = ref;740 return ref;741 }742 function updateRef(initialValue) {743 var hook = updateWorkInProgressHook();744 return hook.memoizedState;745 }746 function mountEffectImpl(fiberFlags, hookFlags, create, deps) {747 var hook = mountWorkInProgressHook();748 var nextDeps = deps === undefined ? null : deps;749 currentlyRenderingFiber$1.flags |= fiberFlags;750 hook.memoizedState = pushEffect(HasEffect | hookFlags, create, undefined, nextDeps);751 }752 function updateEffectImpl(fiberFlags, hookFlags, create, deps) {753 var hook = updateWorkInProgressHook();754 var nextDeps = deps === undefined ? null : deps;755 var destroy = undefined;756 if (currentHook !== null) {757 var prevEffect = currentHook.memoizedState;758 destroy = prevEffect.destroy;759 if (nextDeps !== null) {760 var prevDeps = prevEffect.deps;761 if (areHookInputsEqual(nextDeps, prevDeps)) {762 pushEffect(hookFlags, create, destroy, nextDeps);763 return;764 }765 }766 }767 currentlyRenderingFiber$1.flags |= fiberFlags;768 hook.memoizedState = pushEffect(HasEffect | hookFlags, create, destroy, nextDeps);769 }770 function mountEffect(create, deps) {771 {772 // $FlowExpectedError - jest isn't a global, and isn't recognized outside of tests773 if ('undefined' !== typeof jest) {774 warnIfNotCurrentlyActingEffectsInDEV(currentlyRenderingFiber$1);775 }776 }777 return mountEffectImpl(Update | Passive, Passive$1, create, deps);778 }779 function updateEffect(create, deps) {780 {781 // $FlowExpectedError - jest isn't a global, and isn't recognized outside of tests782 if ('undefined' !== typeof jest) {783 warnIfNotCurrentlyActingEffectsInDEV(currentlyRenderingFiber$1);784 }785 }786 return updateEffectImpl(Update | Passive, Passive$1, create, deps);787 }788 function mountLayoutEffect(create, deps) {789 return mountEffectImpl(Update, Layout, create, deps);790 }791 function updateLayoutEffect(create, deps) {792 return updateEffectImpl(Update, Layout, create, deps);793 }794 function imperativeHandleEffect(create, ref) {795 if (typeof ref === 'function') {796 var refCallback = ref;797 var _inst = create();798 refCallback(_inst);799 return function () {800 refCallback(null);801 };802 } else if (ref !== null && ref !== undefined) {803 var refObject = ref;804 {805 if (!refObject.hasOwnProperty('current')) {806 error('Expected useImperativeHandle() first argument to either be a ' + 'ref callback or React.createRef() object. Instead received: %s.', 'an object with keys {' + Object.keys(refObject).join(', ') + '}');807 }808 }809 var _inst2 = create();810 refObject.current = _inst2;811 return function () {812 refObject.current = null;813 };814 }815 }816 function mountImperativeHandle(ref, create, deps) {817 {818 if (typeof create !== 'function') {819 error('Expected useImperativeHandle() second argument to be a function ' + 'that creates a handle. Instead received: %s.', create !== null ? typeof create : 'null');820 }821 } // TODO: If deps are provided, should we skip comparing the ref itself?822 var effectDeps = deps !== null && deps !== undefined ? deps.concat([ref]) : null;823 return mountEffectImpl(Update, Layout, imperativeHandleEffect.bind(null, create, ref), effectDeps);824 }825 function updateImperativeHandle(ref, create, deps) {826 {827 if (typeof create !== 'function') {828 error('Expected useImperativeHandle() second argument to be a function ' + 'that creates a handle. Instead received: %s.', create !== null ? typeof create : 'null');829 }830 } // TODO: If deps are provided, should we skip comparing the ref itself?831 var effectDeps = deps !== null && deps !== undefined ? deps.concat([ref]) : null;832 return updateEffectImpl(Update, Layout, imperativeHandleEffect.bind(null, create, ref), effectDeps);833 }834 function mountDebugValue(value, formatterFn) {// This hook is normally a no-op.835 // The react-debug-hooks package injects its own implementation836 // so that e.g. DevTools can display custom hook values.837 }838 var updateDebugValue = mountDebugValue;839 function mountCallback(callback, deps) {840 var hook = mountWorkInProgressHook();841 var nextDeps = deps === undefined ? null : deps;842 hook.memoizedState = [callback, nextDeps];843 return callback;844 }845 function updateCallback(callback, deps) {846 var hook = updateWorkInProgressHook();847 var nextDeps = deps === undefined ? null : deps;848 var prevState = hook.memoizedState;849 if (prevState !== null) {850 if (nextDeps !== null) {851 var prevDeps = prevState[1];852 if (areHookInputsEqual(nextDeps, prevDeps)) {853 return prevState[0];854 }855 }856 }857 hook.memoizedState = [callback, nextDeps];858 return callback;859 }860 function mountMemo(nextCreate, deps) {861 var hook = mountWorkInProgressHook();862 var nextDeps = deps === undefined ? null : deps;863 var nextValue = nextCreate();864 hook.memoizedState = [nextValue, nextDeps];865 return nextValue;866 }867 function updateMemo(nextCreate, deps) {868 var hook = updateWorkInProgressHook();869 var nextDeps = deps === undefined ? null : deps;870 var prevState = hook.memoizedState;871 if (prevState !== null) {872 // Assume these are defined. If they're not, areHookInputsEqual will warn.873 if (nextDeps !== null) {874 var prevDeps = prevState[1];875 if (areHookInputsEqual(nextDeps, prevDeps)) {876 return prevState[0];877 }878 }879 }880 var nextValue = nextCreate();881 hook.memoizedState = [nextValue, nextDeps];882 return nextValue;883 }884 function mountDeferredValue(value) {885 var _mountState = mountState(value),886 prevValue = _mountState[0],887 setValue = _mountState[1];888 mountEffect(function () {889 var prevTransition = ReactCurrentBatchConfig$1.transition;890 ReactCurrentBatchConfig$1.transition = 1;891 try {892 setValue(value);893 } finally {894 ReactCurrentBatchConfig$1.transition = prevTransition;895 }896 }, [value]);897 return prevValue;898 }899 function updateDeferredValue(value) {900 var _updateState = updateState(),901 prevValue = _updateState[0],902 setValue = _updateState[1];903 updateEffect(function () {904 var prevTransition = ReactCurrentBatchConfig$1.transition;905 ReactCurrentBatchConfig$1.transition = 1;906 try {907 setValue(value);908 } finally {909 ReactCurrentBatchConfig$1.transition = prevTransition;910 }911 }, [value]);912 return prevValue;913 }914 function rerenderDeferredValue(value) {915 var _rerenderState = rerenderState(),916 prevValue = _rerenderState[0],917 setValue = _rerenderState[1];918 updateEffect(function () {919 var prevTransition = ReactCurrentBatchConfig$1.transition;920 ReactCurrentBatchConfig$1.transition = 1;921 try {922 setValue(value);923 } finally {924 ReactCurrentBatchConfig$1.transition = prevTransition;925 }926 }, [value]);927 return prevValue;928 }929 function startTransition(setPending, callback) {930 var priorityLevel = getCurrentPriorityLevel();931 {932 runWithPriority$1(priorityLevel < UserBlockingPriority$2 ? UserBlockingPriority$2 : priorityLevel, function () {933 setPending(true);934 });935 runWithPriority$1(priorityLevel > NormalPriority$1 ? NormalPriority$1 : priorityLevel, function () {936 var prevTransition = ReactCurrentBatchConfig$1.transition;937 ReactCurrentBatchConfig$1.transition = 1;938 try {939 setPending(false);940 callback();941 } finally {942 ReactCurrentBatchConfig$1.transition = prevTransition;943 }944 });945 }946 }947 function mountTransition() {948 var _mountState2 = mountState(false),949 isPending = _mountState2[0],950 setPending = _mountState2[1]; // The `start` method can be stored on a ref, since `setPending`951 // never changes.952 var start = startTransition.bind(null, setPending);953 mountRef(start);954 return [start, isPending];955 }956 function updateTransition() {957 var _updateState2 = updateState(),958 isPending = _updateState2[0];959 var startRef = updateRef();960 var start = startRef.current;961 return [start, isPending];962 }963 function rerenderTransition() {964 var _rerenderState2 = rerenderState(),965 isPending = _rerenderState2[0];966 var startRef = updateRef();967 var start = startRef.current;968 return [start, isPending];969 }970 var isUpdatingOpaqueValueInRenderPhase = false;971 function getIsUpdatingOpaqueValueInRenderPhaseInDEV() {972 {973 return isUpdatingOpaqueValueInRenderPhase;974 }975 }976 function warnOnOpaqueIdentifierAccessInDEV(fiber) {977 {978 // TODO: Should warn in effects and callbacks, too979 var name = getComponentName(fiber.type) || 'Unknown';980 if (getIsRendering() && !didWarnAboutUseOpaqueIdentifier[name]) {981 error('The object passed back from useOpaqueIdentifier is meant to be ' + 'passed through to attributes only. Do not read the ' + 'value directly.');982 didWarnAboutUseOpaqueIdentifier[name] = true;983 }984 }985 }986 function mountOpaqueIdentifier() {987 var makeId = makeClientIdInDEV.bind(null, warnOnOpaqueIdentifierAccessInDEV.bind(null, currentlyRenderingFiber$1)) ;988 if (getIsHydrating()) {989 var didUpgrade = false;990 var fiber = currentlyRenderingFiber$1;991 var readValue = function () {992 if (!didUpgrade) {993 // Only upgrade once. This works even inside the render phase because994 // the update is added to a shared queue, which outlasts the995 // in-progress render.996 didUpgrade = true;997 {998 isUpdatingOpaqueValueInRenderPhase = true;999 setId(makeId());1000 isUpdatingOpaqueValueInRenderPhase = false;1001 warnOnOpaqueIdentifierAccessInDEV(fiber);1002 }1003 }1004 {1005 {1006 throw Error( "The object passed back from useOpaqueIdentifier is meant to be passed through to attributes only. Do not read the value directly." );1007 }1008 }1009 };1010 var id = makeOpaqueHydratingObject(readValue);1011 var setId = mountState(id)[1];1012 if ((currentlyRenderingFiber$1.mode & BlockingMode) === NoMode) {1013 currentlyRenderingFiber$1.flags |= Update | Passive;1014 pushEffect(HasEffect | Passive$1, function () {1015 setId(makeId());1016 }, undefined, null);1017 }1018 return id;1019 } else {1020 var _id = makeId();1021 mountState(_id);1022 return _id;1023 }1024 }1025 function updateOpaqueIdentifier() {1026 var id = updateState()[0];1027 return id;1028 }1029 function rerenderOpaqueIdentifier() {1030 var id = rerenderState()[0];1031 return id;1032 }1033 function dispatchAction(fiber, queue, action) {1034 {1035 if (typeof arguments[3] === 'function') {1036 error("State updates from the useState() and useReducer() Hooks don't support the " + 'second callback argument. To execute a side effect after ' + 'rendering, declare it in the component body with useEffect().');1037 }1038 }1039 var eventTime = requestEventTime();1040 var lane = requestUpdateLane(fiber);1041 var update = {1042 lane: lane,1043 action: action,1044 eagerReducer: null,1045 eagerState: null,1046 next: null1047 }; // Append the update to the end of the list.1048 var pending = queue.pending;1049 if (pending === null) {1050 // This is the first update. Create a circular list.1051 update.next = update;1052 } else {1053 update.next = pending.next;1054 pending.next = update;1055 }1056 queue.pending = update;1057 var alternate = fiber.alternate;1058 if (fiber === currentlyRenderingFiber$1 || alternate !== null && alternate === currentlyRenderingFiber$1) {1059 // This is a render phase update. Stash it in a lazily-created map of1060 // queue -> linked list of updates. After this render pass, we'll restart1061 // and apply the stashed updates on top of the work-in-progress hook.1062 didScheduleRenderPhaseUpdateDuringThisPass = didScheduleRenderPhaseUpdate = true;1063 } else {1064 if (fiber.lanes === NoLanes && (alternate === null || alternate.lanes === NoLanes)) {1065 // The queue is currently empty, which means we can eagerly compute the1066 // next state before entering the render phase. If the new state is the1067 // same as the current state, we may be able to bail out entirely.1068 var lastRenderedReducer = queue.lastRenderedReducer;1069 if (lastRenderedReducer !== null) {1070 var prevDispatcher;1071 {1072 prevDispatcher = ReactCurrentDispatcher$1.current;1073 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV;1074 }1075 try {1076 var currentState = queue.lastRenderedState;1077 var eagerState = lastRenderedReducer(currentState, action); // Stash the eagerly computed state, and the reducer used to compute1078 // it, on the update object. If the reducer hasn't changed by the1079 // time we enter the render phase, then the eager state can be used1080 // without calling the reducer again.1081 update.eagerReducer = lastRenderedReducer;1082 update.eagerState = eagerState;1083 if (objectIs(eagerState, currentState)) {1084 // Fast path. We can bail out without scheduling React to re-render.1085 // It's still possible that we'll need to rebase this update later,1086 // if the component re-renders for a different reason and by that1087 // time the reducer has changed.1088 return;1089 }1090 } catch (error) {// Suppress the error. It will throw again in the render phase.1091 } finally {1092 {1093 ReactCurrentDispatcher$1.current = prevDispatcher;1094 }1095 }1096 }1097 }1098 {1099 // $FlowExpectedError - jest isn't a global, and isn't recognized outside of tests1100 if ('undefined' !== typeof jest) {1101 warnIfNotScopedWithMatchingAct(fiber);1102 warnIfNotCurrentlyActingUpdatesInDev(fiber);1103 }1104 }1105 scheduleUpdateOnFiber(fiber, lane, eventTime);1106 }1107 {1108 markStateUpdateScheduled(fiber, lane);1109 }1110 }1111 var ContextOnlyDispatcher = {1112 readContext: readContext,1113 useCallback: throwInvalidHookError,1114 useContext: throwInvalidHookError,1115 useEffect: throwInvalidHookError,1116 useImperativeHandle: throwInvalidHookError,1117 useLayoutEffect: throwInvalidHookError,1118 useMemo: throwInvalidHookError,1119 useReducer: throwInvalidHookError,1120 useRef: throwInvalidHookError,1121 useState: throwInvalidHookError,1122 useDebugValue: throwInvalidHookError,1123 useDeferredValue: throwInvalidHookError,1124 useTransition: throwInvalidHookError,1125 useMutableSource: throwInvalidHookError,1126 useOpaqueIdentifier: throwInvalidHookError,1127 unstable_isNewReconciler: enableNewReconciler1128 };1129 var HooksDispatcherOnMountInDEV = null;1130 var HooksDispatcherOnMountWithHookTypesInDEV = null;1131 var HooksDispatcherOnUpdateInDEV = null;1132 var HooksDispatcherOnRerenderInDEV = null;1133 var InvalidNestedHooksDispatcherOnMountInDEV = null;1134 var InvalidNestedHooksDispatcherOnUpdateInDEV = null;1135 var InvalidNestedHooksDispatcherOnRerenderInDEV = null;1136 {1137 var warnInvalidContextAccess = function () {1138 error('Context can only be read while React is rendering. ' + 'In classes, you can read it in the render method or getDerivedStateFromProps. ' + 'In function components, you can read it directly in the function body, but not ' + 'inside Hooks like useReducer() or useMemo().');1139 };1140 var warnInvalidHookAccess = function () {1141 error('Do not call Hooks inside useEffect(...), useMemo(...), or other built-in Hooks. ' + 'You can only call Hooks at the top level of your React function. ' + 'For more information, see ' + 'https://reactjs.org/link/rules-of-hooks');1142 };1143 HooksDispatcherOnMountInDEV = {1144 readContext: function (context, observedBits) {1145 return readContext(context, observedBits);1146 },1147 useCallback: function (callback, deps) {1148 currentHookNameInDev = 'useCallback';1149 mountHookTypesDev();1150 checkDepsAreArrayDev(deps);1151 return mountCallback(callback, deps);1152 },1153 useContext: function (context, observedBits) {1154 currentHookNameInDev = 'useContext';1155 mountHookTypesDev();1156 return readContext(context, observedBits);1157 },1158 useEffect: function (create, deps) {1159 currentHookNameInDev = 'useEffect';1160 mountHookTypesDev();1161 checkDepsAreArrayDev(deps);1162 return mountEffect(create, deps);1163 },1164 useImperativeHandle: function (ref, create, deps) {1165 currentHookNameInDev = 'useImperativeHandle';1166 mountHookTypesDev();1167 checkDepsAreArrayDev(deps);1168 return mountImperativeHandle(ref, create, deps);1169 },1170 useLayoutEffect: function (create, deps) {1171 currentHookNameInDev = 'useLayoutEffect';1172 mountHookTypesDev();1173 checkDepsAreArrayDev(deps);1174 return mountLayoutEffect(create, deps);1175 },1176 useMemo: function (create, deps) {1177 currentHookNameInDev = 'useMemo';1178 mountHookTypesDev();1179 checkDepsAreArrayDev(deps);1180 var prevDispatcher = ReactCurrentDispatcher$1.current;1181 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV;1182 try {1183 return mountMemo(create, deps);1184 } finally {1185 ReactCurrentDispatcher$1.current = prevDispatcher;1186 }1187 },1188 useReducer: function (reducer, initialArg, init) {1189 currentHookNameInDev = 'useReducer';1190 mountHookTypesDev();1191 var prevDispatcher = ReactCurrentDispatcher$1.current;1192 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV;1193 try {1194 return mountReducer(reducer, initialArg, init);1195 } finally {1196 ReactCurrentDispatcher$1.current = prevDispatcher;1197 }1198 },1199 useRef: function (initialValue) {1200 currentHookNameInDev = 'useRef';1201 mountHookTypesDev();1202 return mountRef(initialValue);1203 },1204 useState: function (initialState) {1205 currentHookNameInDev = 'useState';1206 mountHookTypesDev();1207 var prevDispatcher = ReactCurrentDispatcher$1.current;1208 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV;1209 try {1210 return mountState(initialState);1211 } finally {1212 ReactCurrentDispatcher$1.current = prevDispatcher;1213 }1214 },1215 useDebugValue: function (value, formatterFn) {1216 currentHookNameInDev = 'useDebugValue';1217 mountHookTypesDev();1218 return mountDebugValue();1219 },1220 useDeferredValue: function (value) {1221 currentHookNameInDev = 'useDeferredValue';1222 mountHookTypesDev();1223 return mountDeferredValue(value);1224 },1225 useTransition: function () {1226 currentHookNameInDev = 'useTransition';1227 mountHookTypesDev();1228 return mountTransition();1229 },1230 useMutableSource: function (source, getSnapshot, subscribe) {1231 currentHookNameInDev = 'useMutableSource';1232 mountHookTypesDev();1233 return mountMutableSource(source, getSnapshot, subscribe);1234 },1235 useOpaqueIdentifier: function () {1236 currentHookNameInDev = 'useOpaqueIdentifier';1237 mountHookTypesDev();1238 return mountOpaqueIdentifier();1239 },1240 unstable_isNewReconciler: enableNewReconciler1241 };1242 HooksDispatcherOnMountWithHookTypesInDEV = {1243 readContext: function (context, observedBits) {1244 return readContext(context, observedBits);1245 },1246 useCallback: function (callback, deps) {1247 currentHookNameInDev = 'useCallback';1248 updateHookTypesDev();1249 return mountCallback(callback, deps);1250 },1251 useContext: function (context, observedBits) {1252 currentHookNameInDev = 'useContext';1253 updateHookTypesDev();1254 return readContext(context, observedBits);1255 },1256 useEffect: function (create, deps) {1257 currentHookNameInDev = 'useEffect';1258 updateHookTypesDev();1259 return mountEffect(create, deps);1260 },1261 useImperativeHandle: function (ref, create, deps) {1262 currentHookNameInDev = 'useImperativeHandle';1263 updateHookTypesDev();1264 return mountImperativeHandle(ref, create, deps);1265 },1266 useLayoutEffect: function (create, deps) {1267 currentHookNameInDev = 'useLayoutEffect';1268 updateHookTypesDev();1269 return mountLayoutEffect(create, deps);1270 },1271 useMemo: function (create, deps) {1272 currentHookNameInDev = 'useMemo';1273 updateHookTypesDev();1274 var prevDispatcher = ReactCurrentDispatcher$1.current;1275 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV;1276 try {1277 return mountMemo(create, deps);1278 } finally {1279 ReactCurrentDispatcher$1.current = prevDispatcher;1280 }1281 },1282 useReducer: function (reducer, initialArg, init) {1283 currentHookNameInDev = 'useReducer';1284 updateHookTypesDev();1285 var prevDispatcher = ReactCurrentDispatcher$1.current;1286 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV;1287 try {1288 return mountReducer(reducer, initialArg, init);1289 } finally {1290 ReactCurrentDispatcher$1.current = prevDispatcher;1291 }1292 },1293 useRef: function (initialValue) {1294 currentHookNameInDev = 'useRef';1295 updateHookTypesDev();1296 return mountRef(initialValue);1297 },1298 useState: function (initialState) {1299 currentHookNameInDev = 'useState';1300 updateHookTypesDev();1301 var prevDispatcher = ReactCurrentDispatcher$1.current;1302 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV;1303 try {1304 return mountState(initialState);1305 } finally {1306 ReactCurrentDispatcher$1.current = prevDispatcher;1307 }1308 },1309 useDebugValue: function (value, formatterFn) {1310 currentHookNameInDev = 'useDebugValue';1311 updateHookTypesDev();1312 return mountDebugValue();1313 },1314 useDeferredValue: function (value) {1315 currentHookNameInDev = 'useDeferredValue';1316 updateHookTypesDev();1317 return mountDeferredValue(value);1318 },1319 useTransition: function () {1320 currentHookNameInDev = 'useTransition';1321 updateHookTypesDev();1322 return mountTransition();1323 },1324 useMutableSource: function (source, getSnapshot, subscribe) {1325 currentHookNameInDev = 'useMutableSource';1326 updateHookTypesDev();1327 return mountMutableSource(source, getSnapshot, subscribe);1328 },1329 useOpaqueIdentifier: function () {1330 currentHookNameInDev = 'useOpaqueIdentifier';1331 updateHookTypesDev();1332 return mountOpaqueIdentifier();1333 },1334 unstable_isNewReconciler: enableNewReconciler1335 };1336 HooksDispatcherOnUpdateInDEV = {1337 readContext: function (context, observedBits) {1338 return readContext(context, observedBits);1339 },1340 useCallback: function (callback, deps) {1341 currentHookNameInDev = 'useCallback';1342 updateHookTypesDev();1343 return updateCallback(callback, deps);1344 },1345 useContext: function (context, observedBits) {1346 currentHookNameInDev = 'useContext';1347 updateHookTypesDev();1348 return readContext(context, observedBits);1349 },1350 useEffect: function (create, deps) {1351 currentHookNameInDev = 'useEffect';1352 updateHookTypesDev();1353 return updateEffect(create, deps);1354 },1355 useImperativeHandle: function (ref, create, deps) {1356 currentHookNameInDev = 'useImperativeHandle';1357 updateHookTypesDev();1358 return updateImperativeHandle(ref, create, deps);1359 },1360 useLayoutEffect: function (create, deps) {1361 currentHookNameInDev = 'useLayoutEffect';1362 updateHookTypesDev();1363 return updateLayoutEffect(create, deps);1364 },1365 useMemo: function (create, deps) {1366 currentHookNameInDev = 'useMemo';1367 updateHookTypesDev();1368 var prevDispatcher = ReactCurrentDispatcher$1.current;1369 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV;1370 try {1371 return updateMemo(create, deps);1372 } finally {1373 ReactCurrentDispatcher$1.current = prevDispatcher;1374 }1375 },1376 useReducer: function (reducer, initialArg, init) {1377 currentHookNameInDev = 'useReducer';1378 updateHookTypesDev();1379 var prevDispatcher = ReactCurrentDispatcher$1.current;1380 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV;1381 try {1382 return updateReducer(reducer, initialArg, init);1383 } finally {1384 ReactCurrentDispatcher$1.current = prevDispatcher;1385 }1386 },1387 useRef: function (initialValue) {1388 currentHookNameInDev = 'useRef';1389 updateHookTypesDev();1390 return updateRef();1391 },1392 useState: function (initialState) {1393 currentHookNameInDev = 'useState';1394 updateHookTypesDev();1395 var prevDispatcher = ReactCurrentDispatcher$1.current;1396 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV;1397 try {1398 return updateState(initialState);1399 } finally {1400 ReactCurrentDispatcher$1.current = prevDispatcher;1401 }1402 },1403 useDebugValue: function (value, formatterFn) {1404 currentHookNameInDev = 'useDebugValue';1405 updateHookTypesDev();1406 return updateDebugValue();1407 },1408 useDeferredValue: function (value) {1409 currentHookNameInDev = 'useDeferredValue';1410 updateHookTypesDev();1411 return updateDeferredValue(value);1412 },1413 useTransition: function () {1414 currentHookNameInDev = 'useTransition';1415 updateHookTypesDev();1416 return updateTransition();1417 },1418 useMutableSource: function (source, getSnapshot, subscribe) {1419 currentHookNameInDev = 'useMutableSource';1420 updateHookTypesDev();1421 return updateMutableSource(source, getSnapshot, subscribe);1422 },1423 useOpaqueIdentifier: function () {1424 currentHookNameInDev = 'useOpaqueIdentifier';1425 updateHookTypesDev();1426 return updateOpaqueIdentifier();1427 },1428 unstable_isNewReconciler: enableNewReconciler1429 };1430 HooksDispatcherOnRerenderInDEV = {1431 readContext: function (context, observedBits) {1432 return readContext(context, observedBits);1433 },1434 useCallback: function (callback, deps) {1435 currentHookNameInDev = 'useCallback';1436 updateHookTypesDev();1437 return updateCallback(callback, deps);1438 },1439 useContext: function (context, observedBits) {1440 currentHookNameInDev = 'useContext';1441 updateHookTypesDev();1442 return readContext(context, observedBits);1443 },1444 useEffect: function (create, deps) {1445 currentHookNameInDev = 'useEffect';1446 updateHookTypesDev();1447 return updateEffect(create, deps);1448 },1449 useImperativeHandle: function (ref, create, deps) {1450 currentHookNameInDev = 'useImperativeHandle';1451 updateHookTypesDev();1452 return updateImperativeHandle(ref, create, deps);1453 },1454 useLayoutEffect: function (create, deps) {1455 currentHookNameInDev = 'useLayoutEffect';1456 updateHookTypesDev();1457 return updateLayoutEffect(create, deps);1458 },1459 useMemo: function (create, deps) {1460 currentHookNameInDev = 'useMemo';1461 updateHookTypesDev();1462 var prevDispatcher = ReactCurrentDispatcher$1.current;1463 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnRerenderInDEV;1464 try {1465 return updateMemo(create, deps);1466 } finally {1467 ReactCurrentDispatcher$1.current = prevDispatcher;1468 }1469 },1470 useReducer: function (reducer, initialArg, init) {1471 currentHookNameInDev = 'useReducer';1472 updateHookTypesDev();1473 var prevDispatcher = ReactCurrentDispatcher$1.current;1474 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnRerenderInDEV;1475 try {1476 return rerenderReducer(reducer, initialArg, init);1477 } finally {1478 ReactCurrentDispatcher$1.current = prevDispatcher;1479 }1480 },1481 useRef: function (initialValue) {1482 currentHookNameInDev = 'useRef';1483 updateHookTypesDev();1484 return updateRef();1485 },1486 useState: function (initialState) {1487 currentHookNameInDev = 'useState';1488 updateHookTypesDev();1489 var prevDispatcher = ReactCurrentDispatcher$1.current;1490 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnRerenderInDEV;1491 try {1492 return rerenderState(initialState);1493 } finally {1494 ReactCurrentDispatcher$1.current = prevDispatcher;1495 }1496 },1497 useDebugValue: function (value, formatterFn) {1498 currentHookNameInDev = 'useDebugValue';1499 updateHookTypesDev();1500 return updateDebugValue();1501 },1502 useDeferredValue: function (value) {1503 currentHookNameInDev = 'useDeferredValue';1504 updateHookTypesDev();1505 return rerenderDeferredValue(value);1506 },1507 useTransition: function () {1508 currentHookNameInDev = 'useTransition';1509 updateHookTypesDev();1510 return rerenderTransition();1511 },1512 useMutableSource: function (source, getSnapshot, subscribe) {1513 currentHookNameInDev = 'useMutableSource';1514 updateHookTypesDev();1515 return updateMutableSource(source, getSnapshot, subscribe);1516 },1517 useOpaqueIdentifier: function () {1518 currentHookNameInDev = 'useOpaqueIdentifier';1519 updateHookTypesDev();1520 return rerenderOpaqueIdentifier();1521 },1522 unstable_isNewReconciler: enableNewReconciler1523 };1524 InvalidNestedHooksDispatcherOnMountInDEV = {1525 readContext: function (context, observedBits) {1526 warnInvalidContextAccess();1527 return readContext(context, observedBits);1528 },1529 useCallback: function (callback, deps) {1530 currentHookNameInDev = 'useCallback';1531 warnInvalidHookAccess();1532 mountHookTypesDev();1533 return mountCallback(callback, deps);1534 },1535 useContext: function (context, observedBits) {1536 currentHookNameInDev = 'useContext';1537 warnInvalidHookAccess();1538 mountHookTypesDev();1539 return readContext(context, observedBits);1540 },1541 useEffect: function (create, deps) {1542 currentHookNameInDev = 'useEffect';1543 warnInvalidHookAccess();1544 mountHookTypesDev();1545 return mountEffect(create, deps);1546 },1547 useImperativeHandle: function (ref, create, deps) {1548 currentHookNameInDev = 'useImperativeHandle';1549 warnInvalidHookAccess();1550 mountHookTypesDev();1551 return mountImperativeHandle(ref, create, deps);1552 },1553 useLayoutEffect: function (create, deps) {1554 currentHookNameInDev = 'useLayoutEffect';1555 warnInvalidHookAccess();1556 mountHookTypesDev();1557 return mountLayoutEffect(create, deps);1558 },1559 useMemo: function (create, deps) {1560 currentHookNameInDev = 'useMemo';1561 warnInvalidHookAccess();1562 mountHookTypesDev();1563 var prevDispatcher = ReactCurrentDispatcher$1.current;1564 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV;1565 try {1566 return mountMemo(create, deps);1567 } finally {1568 ReactCurrentDispatcher$1.current = prevDispatcher;1569 }1570 },1571 useReducer: function (reducer, initialArg, init) {1572 currentHookNameInDev = 'useReducer';1573 warnInvalidHookAccess();1574 mountHookTypesDev();1575 var prevDispatcher = ReactCurrentDispatcher$1.current;1576 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV;1577 try {1578 return mountReducer(reducer, initialArg, init);1579 } finally {1580 ReactCurrentDispatcher$1.current = prevDispatcher;1581 }1582 },1583 useRef: function (initialValue) {1584 currentHookNameInDev = 'useRef';1585 warnInvalidHookAccess();1586 mountHookTypesDev();1587 return mountRef(initialValue);1588 },1589 useState: function (initialState) {1590 currentHookNameInDev = 'useState';1591 warnInvalidHookAccess();1592 mountHookTypesDev();1593 var prevDispatcher = ReactCurrentDispatcher$1.current;1594 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV;1595 try {1596 return mountState(initialState);1597 } finally {1598 ReactCurrentDispatcher$1.current = prevDispatcher;1599 }1600 },1601 useDebugValue: function (value, formatterFn) {1602 currentHookNameInDev = 'useDebugValue';1603 warnInvalidHookAccess();1604 mountHookTypesDev();1605 return mountDebugValue();1606 },1607 useDeferredValue: function (value) {1608 currentHookNameInDev = 'useDeferredValue';1609 warnInvalidHookAccess();1610 mountHookTypesDev();1611 return mountDeferredValue(value);1612 },1613 useTransition: function () {1614 currentHookNameInDev = 'useTransition';1615 warnInvalidHookAccess();1616 mountHookTypesDev();1617 return mountTransition();1618 },1619 useMutableSource: function (source, getSnapshot, subscribe) {1620 currentHookNameInDev = 'useMutableSource';1621 warnInvalidHookAccess();1622 mountHookTypesDev();1623 return mountMutableSource(source, getSnapshot, subscribe);1624 },1625 useOpaqueIdentifier: function () {1626 currentHookNameInDev = 'useOpaqueIdentifier';1627 warnInvalidHookAccess();1628 mountHookTypesDev();1629 return mountOpaqueIdentifier();1630 },1631 unstable_isNewReconciler: enableNewReconciler1632 };1633 InvalidNestedHooksDispatcherOnUpdateInDEV = {1634 readContext: function (context, observedBits) {1635 warnInvalidContextAccess();1636 return readContext(context, observedBits);1637 },1638 useCallback: function (callback, deps) {1639 currentHookNameInDev = 'useCallback';1640 warnInvalidHookAccess();1641 updateHookTypesDev();1642 return updateCallback(callback, deps);...

Full Screen

Full Screen

ReactFiberHooks.js

Source:ReactFiberHooks.js Github

copy

Full Screen

...172// In DEV, this tracks whether currently rendering component needs to ignore173// the dependencies for Hooks that need them (e.g. useEffect or useMemo).174// When true, such Hooks will always be "remounted". Only used during hot reload.175let ignorePreviousDependencies: boolean = false;176function mountHookTypesDev() {177 if (true) {178 const hookName = ((currentHookNameInDev: any): HookType);179 if (hookTypesDev === null) {180 hookTypesDev = [hookName];181 } else {182 hookTypesDev.push(hookName);183 }184 }185}186function updateHookTypesDev() {187 if (true) {188 const hookName = ((currentHookNameInDev: any): HookType);189 if (hookTypesDev !== null) {190 hookTypesUpdateIndexDev++;191 if (hookTypesDev[hookTypesUpdateIndexDev] !== hookName) {192 warnOnHookMismatchInDev(hookName);193 }194 }195 }196}197function checkDepsAreArrayDev(deps: mixed) {198 if (true) {199 if (deps !== undefined && deps !== null && !Array.isArray(deps)) {200 // Verify deps, but only on mount to avoid extra checks.201 // It's unlikely their type would change as usually you define them inline.202 console.error(203 '%s received a final argument that is not an array (instead, received `%s`). When ' +204 'specified, the final argument must be an array.',205 currentHookNameInDev,206 typeof deps,207 );208 }209 }210}211function warnOnHookMismatchInDev(currentHookName: HookType) {212 if (true) {213 const componentName = getComponentName(currentlyRenderingFiber.type);214 if (!didWarnAboutMismatchedHooksForComponent.has(componentName)) {215 didWarnAboutMismatchedHooksForComponent.add(componentName);216 if (hookTypesDev !== null) {217 let table = '';218 const secondColumnStart = 30;219 for (let i = 0; i <= ((hookTypesUpdateIndexDev: any): number); i++) {220 const oldHookName = hookTypesDev[i];221 const newHookName =222 i === ((hookTypesUpdateIndexDev: any): number)223 ? currentHookName224 : oldHookName;225 let row = `${i + 1}. ${oldHookName}`;226 // Extra space so second column lines up227 // lol @ IE not supporting String#repeat228 while (row.length < secondColumnStart) {229 row += ' ';230 }231 row += newHookName + '\n';232 table += row;233 }234 console.error(235 'React has detected a change in the order of Hooks called by %s. ' +236 'This will lead to bugs and errors if not fixed. ' +237 'For more information, read the Rules of Hooks: https://fb.me/rules-of-hooks\n\n' +238 ' Previous render Next render\n' +239 ' ------------------------------------------------------\n' +240 '%s' +241 ' ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n',242 componentName,243 table,244 );245 }246 }247 }248}249function throwInvalidHookError() {250 invariant(251 false,252 'Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for' +253 ' one of the following reasons:\n' +254 '1. You might have mismatching versions of React and the renderer (such as React DOM)\n' +255 '2. You might be breaking the Rules of Hooks\n' +256 '3. You might have more than one copy of React in the same app\n' +257 'See https://fb.me/react-invalid-hook-call for tips about how to debug and fix this problem.',258 );259}260function areHookInputsEqual(261 nextDeps: Array<mixed>,262 prevDeps: Array<mixed> | null,263) {264 if (true) {265 if (ignorePreviousDependencies) {266 // Only true when this component is being hot reloaded.267 return false;268 }269 }270 if (prevDeps === null) {271 if (true) {272 console.error(273 '%s received a final argument during this render, but not during ' +274 'the previous render. Even though the final argument is optional, ' +275 'its type cannot change between renders.',276 currentHookNameInDev,277 );278 }279 return false;280 }281 if (true) {282 // Don't bother comparing lengths in prod because these arrays should be283 // passed inline.284 if (nextDeps.length !== prevDeps.length) {285 console.error(286 'The final argument passed to %s changed size between renders. The ' +287 'order and size of this array must remain constant.\n\n' +288 'Previous: %s\n' +289 'Incoming: %s',290 currentHookNameInDev,291 `[${prevDeps.join(', ')}]`,292 `[${nextDeps.join(', ')}]`,293 );294 }295 }296 for (let i = 0; i < prevDeps.length && i < nextDeps.length; i++) {297 if (is(nextDeps[i], prevDeps[i])) {298 continue;299 }300 return false;301 }302 return true;303}304export function renderWithHooks(305 current: Fiber | null,306 workInProgress: Fiber,307 Component: any,308 props: any,309 secondArg: any,310 nextRenderExpirationTime: ExpirationTime,311): any {312 renderExpirationTime = nextRenderExpirationTime;313 currentlyRenderingFiber = workInProgress;314 if (true) {315 hookTypesDev =316 current !== null317 ? ((current._debugHookTypes: any): Array<HookType>)318 : null;319 hookTypesUpdateIndexDev = -1;320 // Used for hot reloading:321 ignorePreviousDependencies =322 current !== null && current.type !== workInProgress.type;323 }324 workInProgress.memoizedState = null;325 workInProgress.updateQueue = null;326 workInProgress.expirationTime = NoWork;327 // The following should have already been reset328 // currentHook = null;329 // workInProgressHook = null;330 // didScheduleRenderPhaseUpdate = false;331 // TODO Warn if no hooks are used at all during mount, then some are used during update.332 // Currently we will identify the update render as a mount because memoizedState === null.333 // This is tricky because it's valid for certain types of components (e.g. React.lazy)334 // Using memoizedState to differentiate between mount/update only works if at least one stateful hook is used.335 // Non-stateful hooks (e.g. context) don't get added to memoizedState,336 // so memoizedState would be null during updates and mounts.337 if (true) {338 if (current !== null && current.memoizedState !== null) {339 ReactCurrentDispatcher.current = HooksDispatcherOnUpdateInDEV;340 } else if (hookTypesDev !== null) {341 // This dispatcher handles an edge case where a component is updating,342 // but no stateful hooks have been used.343 // We want to match the production code behavior (which will use HooksDispatcherOnMount),344 // but with the extra DEV validation to ensure hooks ordering hasn't changed.345 // This dispatcher does that.346 ReactCurrentDispatcher.current = HooksDispatcherOnMountWithHookTypesInDEV;347 } else {348 ReactCurrentDispatcher.current = HooksDispatcherOnMountInDEV;349 }350 } else {351 ReactCurrentDispatcher.current =352 current === null || current.memoizedState === null353 ? HooksDispatcherOnMount354 : HooksDispatcherOnUpdate;355 }356 let children = Component(props, secondArg);357 // Check if there was a render phase update358 if (workInProgress.expirationTime === renderExpirationTime) {359 // Keep rendering in a loop for as long as render phase updates continue to360 // be scheduled. Use a counter to prevent infinite loops.361 let numberOfReRenders: number = 0;362 do {363 workInProgress.expirationTime = NoWork;364 invariant(365 numberOfReRenders < RE_RENDER_LIMIT,366 'Too many re-renders. React limits the number of renders to prevent ' +367 'an infinite loop.',368 );369 numberOfReRenders += 1;370 if (true) {371 // Even when hot reloading, allow dependencies to stabilize372 // after first render to prevent infinite render phase updates.373 ignorePreviousDependencies = false;374 }375 // Start over from the beginning of the list376 currentHook = null;377 workInProgressHook = null;378 workInProgress.updateQueue = null;379 if (true) {380 // Also validate hook order for cascading updates.381 hookTypesUpdateIndexDev = -1;382 }383 ReactCurrentDispatcher.current = true384 ? HooksDispatcherOnRerenderInDEV385 : HooksDispatcherOnRerender;386 children = Component(props, secondArg);387 } while (workInProgress.expirationTime === renderExpirationTime);388 }389 // We can assume the previous dispatcher is always this one, since we set it390 // at the beginning of the render phase and there's no re-entrancy.391 ReactCurrentDispatcher.current = ContextOnlyDispatcher;392 if (true) {393 workInProgress._debugHookTypes = hookTypesDev;394 }395 // This check uses currentHook so that it works the same in DEV and prod bundles.396 // hookTypesDev could catch more cases (e.g. context) but only in DEV bundles.397 const didRenderTooFewHooks =398 currentHook !== null && currentHook.next !== null;399 renderExpirationTime = NoWork;400 currentlyRenderingFiber = (null: any);401 currentHook = null;402 workInProgressHook = null;403 if (true) {404 currentHookNameInDev = null;405 hookTypesDev = null;406 hookTypesUpdateIndexDev = -1;407 }408 didScheduleRenderPhaseUpdate = false;409 invariant(410 !didRenderTooFewHooks,411 'Rendered fewer hooks than expected. This may be caused by an accidental ' +412 'early return statement.',413 );414 return children;415}416export function bailoutHooks(417 current: Fiber,418 workInProgress: Fiber,419 expirationTime: ExpirationTime,420) {421 workInProgress.updateQueue = current.updateQueue;422 workInProgress.effectTag &= ~(PassiveEffect | UpdateEffect);423 if (current.expirationTime <= expirationTime) {424 current.expirationTime = NoWork;425 }426}427export function resetHooksAfterThrow(): void {428 // We can assume the previous dispatcher is always this one, since we set it429 // at the beginning of the render phase and there's no re-entrancy.430 ReactCurrentDispatcher.current = ContextOnlyDispatcher;431 if (didScheduleRenderPhaseUpdate) {432 // There were render phase updates. These are only valid for this render433 // phase, which we are now aborting. Remove the updates from the queues so434 // they do not persist to the next render. Do not remove updates from hooks435 // that weren't processed.436 //437 // Only reset the updates from the queue if it has a clone. If it does438 // not have a clone, that means it wasn't processed, and the updates were439 // scheduled before we entered the render phase.440 let hook: Hook | null = currentlyRenderingFiber.memoizedState;441 while (hook !== null) {442 const queue = hook.queue;443 if (queue !== null) {444 queue.pending = null;445 }446 hook = hook.next;447 }448 }449 renderExpirationTime = NoWork;450 currentlyRenderingFiber = (null: any);451 currentHook = null;452 workInProgressHook = null;453 if (true) {454 hookTypesDev = null;455 hookTypesUpdateIndexDev = -1;456 currentHookNameInDev = null;457 }458 didScheduleRenderPhaseUpdate = false;459}460function mountWorkInProgressHook(): Hook {461 const hook: Hook = {462 memoizedState: null,463 baseState: null,464 baseQueue: null,465 queue: null,466 next: null,467 };468 if (workInProgressHook === null) {469 // This is the first hook in the list470 currentlyRenderingFiber.memoizedState = workInProgressHook = hook;471 } else {472 // Append to the end of the list473 workInProgressHook = workInProgressHook.next = hook;474 }475 return workInProgressHook;476}477function updateWorkInProgressHook(): Hook {478 // This function is used both for updates and for re-renders triggered by a479 // render phase update. It assumes there is either a current hook we can480 // clone, or a work-in-progress hook from a previous render pass that we can481 // use as a base. When we reach the end of the base list, we must switch to482 // the dispatcher used for mounts.483 let nextCurrentHook: null | Hook;484 if (currentHook === null) {485 let current = currentlyRenderingFiber.alternate;486 if (current !== null) {487 nextCurrentHook = current.memoizedState;488 } else {489 nextCurrentHook = null;490 }491 } else {492 nextCurrentHook = currentHook.next;493 }494 let nextWorkInProgressHook: null | Hook;495 if (workInProgressHook === null) {496 nextWorkInProgressHook = currentlyRenderingFiber.memoizedState;497 } else {498 nextWorkInProgressHook = workInProgressHook.next;499 }500 if (nextWorkInProgressHook !== null) {501 // There's already a work-in-progress. Reuse it.502 workInProgressHook = nextWorkInProgressHook;503 nextWorkInProgressHook = workInProgressHook.next;504 currentHook = nextCurrentHook;505 } else {506 // Clone from the current hook.507 invariant(508 nextCurrentHook !== null,509 'Rendered more hooks than during the previous render.',510 );511 currentHook = nextCurrentHook;512 const newHook: Hook = {513 memoizedState: currentHook.memoizedState,514 baseState: currentHook.baseState,515 baseQueue: currentHook.baseQueue,516 queue: currentHook.queue,517 next: null,518 };519 if (workInProgressHook === null) {520 // This is the first hook in the list.521 currentlyRenderingFiber.memoizedState = workInProgressHook = newHook;522 } else {523 // Append to the end of the list.524 workInProgressHook = workInProgressHook.next = newHook;525 }526 }527 return workInProgressHook;528}529function createFunctionComponentUpdateQueue(): FunctionComponentUpdateQueue {530 return {531 lastEffect: null,532 };533}534function basicStateReducer<S>(state: S, action: BasicStateAction<S>): S {535 // $FlowFixMe: Flow doesn't like mixed types536 return typeof action === 'function' ? action(state) : action;537}538function mountReducer<S, I, A>(539 reducer: (S, A) => S,540 initialArg: I,541 init?: I => S,542): [S, Dispatch<A>] {543 const hook = mountWorkInProgressHook();544 let initialState;545 if (init !== undefined) {546 initialState = init(initialArg);547 } else {548 initialState = ((initialArg: any): S);549 }550 hook.memoizedState = hook.baseState = initialState;551 const queue = (hook.queue = {552 pending: null,553 dispatch: null,554 lastRenderedReducer: reducer,555 lastRenderedState: (initialState: any),556 });557 const dispatch: Dispatch<A> = (queue.dispatch = (dispatchAction.bind(558 null,559 currentlyRenderingFiber,560 queue,561 ): any));562 return [hook.memoizedState, dispatch];563}564function updateReducer<S, I, A>(565 reducer: (S, A) => S,566 initialArg: I,567 init?: I => S,568): [S, Dispatch<A>] {569 const hook = updateWorkInProgressHook();570 const queue = hook.queue;571 invariant(572 queue !== null,573 'Should have a queue. This is likely a bug in React. Please file an issue.',574 );575 queue.lastRenderedReducer = reducer;576 const current: Hook = (currentHook: any);577 // The last rebase update that is NOT part of the base state.578 let baseQueue = current.baseQueue;579 // The last pending update that hasn't been processed yet.580 let pendingQueue = queue.pending;581 if (pendingQueue !== null) {582 // We have new updates that haven't been processed yet.583 // We'll add them to the base queue.584 if (baseQueue !== null) {585 // Merge the pending queue and the base queue.586 let baseFirst = baseQueue.next;587 let pendingFirst = pendingQueue.next;588 baseQueue.next = pendingFirst;589 pendingQueue.next = baseFirst;590 }591 current.baseQueue = baseQueue = pendingQueue;592 queue.pending = null;593 }594 if (baseQueue !== null) {595 // We have a queue to process.596 let first = baseQueue.next;597 let newState = current.baseState;598 let newBaseState = null;599 let newBaseQueueFirst = null;600 let newBaseQueueLast = null;601 let update = first;602 do {603 const updateExpirationTime = update.expirationTime;604 if (updateExpirationTime < renderExpirationTime) {605 // Priority is insufficient. Skip this update. If this is the first606 // skipped update, the previous update/state is the new base607 // update/state.608 const clone: Update<S, A> = {609 expirationTime: update.expirationTime,610 suspenseConfig: update.suspenseConfig,611 action: update.action,612 eagerReducer: update.eagerReducer,613 eagerState: update.eagerState,614 next: (null: any),615 };616 if (newBaseQueueLast === null) {617 newBaseQueueFirst = newBaseQueueLast = clone;618 newBaseState = newState;619 } else {620 newBaseQueueLast = newBaseQueueLast.next = clone;621 }622 // Update the remaining priority in the queue.623 if (updateExpirationTime > currentlyRenderingFiber.expirationTime) {624 currentlyRenderingFiber.expirationTime = updateExpirationTime;625 markUnprocessedUpdateTime(updateExpirationTime);626 }627 } else {628 // This update does have sufficient priority.629 if (newBaseQueueLast !== null) {630 const clone: Update<S, A> = {631 expirationTime: Sync, // This update is going to be committed so we never want uncommit it.632 suspenseConfig: update.suspenseConfig,633 action: update.action,634 eagerReducer: update.eagerReducer,635 eagerState: update.eagerState,636 next: (null: any),637 };638 newBaseQueueLast = newBaseQueueLast.next = clone;639 }640 // Mark the event time of this update as relevant to this render pass.641 // TODO: This should ideally use the true event time of this update rather than642 // its priority which is a derived and not reverseable value.643 // TODO: We should skip this update if it was already committed but currently644 // we have no way of detecting the difference between a committed and suspended645 // update here.646 markRenderEventTimeAndConfig(647 updateExpirationTime,648 update.suspenseConfig,649 );650 // Process this update.651 if (update.eagerReducer === reducer) {652 // If this update was processed eagerly, and its reducer matches the653 // current reducer, we can use the eagerly computed state.654 newState = ((update.eagerState: any): S);655 } else {656 const action = update.action;657 newState = reducer(newState, action);658 }659 }660 update = update.next;661 } while (update !== null && update !== first);662 if (newBaseQueueLast === null) {663 newBaseState = newState;664 } else {665 newBaseQueueLast.next = (newBaseQueueFirst: any);666 }667 // Mark that the fiber performed work, but only if the new state is668 // different from the current state.669 if (!is(newState, hook.memoizedState)) {670 markWorkInProgressReceivedUpdate();671 }672 hook.memoizedState = newState;673 hook.baseState = newBaseState;674 hook.baseQueue = newBaseQueueLast;675 queue.lastRenderedState = newState;676 }677 const dispatch: Dispatch<A> = (queue.dispatch: any);678 return [hook.memoizedState, dispatch];679}680function rerenderReducer<S, I, A>(681 reducer: (S, A) => S,682 initialArg: I,683 init?: I => S,684): [S, Dispatch<A>] {685 const hook = updateWorkInProgressHook();686 const queue = hook.queue;687 invariant(688 queue !== null,689 'Should have a queue. This is likely a bug in React. Please file an issue.',690 );691 queue.lastRenderedReducer = reducer;692 // This is a re-render. Apply the new render phase updates to the previous693 // work-in-progress hook.694 const dispatch: Dispatch<A> = (queue.dispatch: any);695 const lastRenderPhaseUpdate = queue.pending;696 let newState = hook.memoizedState;697 if (lastRenderPhaseUpdate !== null) {698 // The queue doesn't persist past this render pass.699 queue.pending = null;700 const firstRenderPhaseUpdate = lastRenderPhaseUpdate.next;701 let update = firstRenderPhaseUpdate;702 do {703 // Process this render phase update. We don't have to check the704 // priority because it will always be the same as the current705 // render's.706 const action = update.action;707 newState = reducer(newState, action);708 update = update.next;709 } while (update !== firstRenderPhaseUpdate);710 // Mark that the fiber performed work, but only if the new state is711 // different from the current state.712 if (!is(newState, hook.memoizedState)) {713 markWorkInProgressReceivedUpdate();714 }715 hook.memoizedState = newState;716 // Don't persist the state accumulated from the render phase updates to717 // the base state unless the queue is empty.718 // TODO: Not sure if this is the desired semantics, but it's what we719 // do for gDSFP. I can't remember why.720 if (hook.baseQueue === null) {721 hook.baseState = newState;722 }723 queue.lastRenderedState = newState;724 }725 return [newState, dispatch];726}727function mountState<S>(728 initialState: (() => S) | S,729): [S, Dispatch<BasicStateAction<S>>] {730 const hook = mountWorkInProgressHook();731 if (typeof initialState === 'function') {732 // $FlowFixMe: Flow doesn't like mixed types733 initialState = initialState();734 }735 hook.memoizedState = hook.baseState = initialState;736 const queue = (hook.queue = {737 pending: null,738 dispatch: null,739 lastRenderedReducer: basicStateReducer,740 lastRenderedState: (initialState: any),741 });742 const dispatch: Dispatch<743 BasicStateAction<S>,744 > = (queue.dispatch = (dispatchAction.bind(745 null,746 currentlyRenderingFiber,747 queue,748 ): any));749 return [hook.memoizedState, dispatch];750}751function updateState<S>(752 initialState: (() => S) | S,753): [S, Dispatch<BasicStateAction<S>>] {754 return updateReducer(basicStateReducer, (initialState: any));755}756function rerenderState<S>(757 initialState: (() => S) | S,758): [S, Dispatch<BasicStateAction<S>>] {759 return rerenderReducer(basicStateReducer, (initialState: any));760}761function pushEffect(tag, create, destroy, deps) {762 const effect: Effect = {763 tag,764 create,765 destroy,766 deps,767 // Circular768 next: (null: any),769 };770 let componentUpdateQueue: null | FunctionComponentUpdateQueue = (currentlyRenderingFiber.updateQueue: any);771 if (componentUpdateQueue === null) {772 componentUpdateQueue = createFunctionComponentUpdateQueue();773 currentlyRenderingFiber.updateQueue = (componentUpdateQueue: any);774 componentUpdateQueue.lastEffect = effect.next = effect;775 } else {776 const lastEffect = componentUpdateQueue.lastEffect;777 if (lastEffect === null) {778 componentUpdateQueue.lastEffect = effect.next = effect;779 } else {780 const firstEffect = lastEffect.next;781 lastEffect.next = effect;782 effect.next = firstEffect;783 componentUpdateQueue.lastEffect = effect;784 }785 }786 return effect;787}788function mountRef<T>(initialValue: T): {|current: T|} {789 const hook = mountWorkInProgressHook();790 const ref = {current: initialValue};791 if (true) {792 Object.seal(ref);793 }794 hook.memoizedState = ref;795 return ref;796}797function updateRef<T>(initialValue: T): {|current: T|} {798 const hook = updateWorkInProgressHook();799 return hook.memoizedState;800}801function mountEffectImpl(fiberEffectTag, hookEffectTag, create, deps): void {802 const hook = mountWorkInProgressHook();803 const nextDeps = deps === undefined ? null : deps;804 currentlyRenderingFiber.effectTag |= fiberEffectTag;805 hook.memoizedState = pushEffect(806 HookHasEffect | hookEffectTag,807 create,808 undefined,809 nextDeps,810 );811}812function updateEffectImpl(fiberEffectTag, hookEffectTag, create, deps): void {813 const hook = updateWorkInProgressHook();814 const nextDeps = deps === undefined ? null : deps;815 let destroy = undefined;816 if (currentHook !== null) {817 const prevEffect = currentHook.memoizedState;818 destroy = prevEffect.destroy;819 if (nextDeps !== null) {820 const prevDeps = prevEffect.deps;821 if (areHookInputsEqual(nextDeps, prevDeps)) {822 pushEffect(hookEffectTag, create, destroy, nextDeps);823 return;824 }825 }826 }827 currentlyRenderingFiber.effectTag |= fiberEffectTag;828 hook.memoizedState = pushEffect(829 HookHasEffect | hookEffectTag,830 create,831 destroy,832 nextDeps,833 );834}835function mountEffect(836 create: () => (() => void) | void,837 deps: Array<mixed> | void | null,838): void {839 if (true) {840 // $FlowExpectedError - jest isn't a global, and isn't recognized outside of tests841 if ('undefined' !== typeof jest) {842 warnIfNotCurrentlyActingEffectsInDEV(currentlyRenderingFiber);843 }844 }845 return mountEffectImpl(846 UpdateEffect | PassiveEffect,847 HookPassive,848 create,849 deps,850 );851}852function updateEffect(853 create: () => (() => void) | void,854 deps: Array<mixed> | void | null,855): void {856 if (true) {857 // $FlowExpectedError - jest isn't a global, and isn't recognized outside of tests858 if ('undefined' !== typeof jest) {859 warnIfNotCurrentlyActingEffectsInDEV(currentlyRenderingFiber);860 }861 }862 return updateEffectImpl(863 UpdateEffect | PassiveEffect,864 HookPassive,865 create,866 deps,867 );868}869function mountLayoutEffect(870 create: () => (() => void) | void,871 deps: Array<mixed> | void | null,872): void {873 return mountEffectImpl(UpdateEffect, HookLayout, create, deps);874}875function updateLayoutEffect(876 create: () => (() => void) | void,877 deps: Array<mixed> | void | null,878): void {879 return updateEffectImpl(UpdateEffect, HookLayout, create, deps);880}881function imperativeHandleEffect<T>(882 create: () => T,883 ref: {|current: T | null|} | ((inst: T | null) => mixed) | null | void,884) {885 if (typeof ref === 'function') {886 const refCallback = ref;887 const inst = create();888 refCallback(inst);889 return () => {890 refCallback(null);891 };892 } else if (ref !== null && ref !== undefined) {893 const refObject = ref;894 if (true) {895 if (!refObject.hasOwnProperty('current')) {896 console.error(897 'Expected useImperativeHandle() first argument to either be a ' +898 'ref callback or React.createRef() object. Instead received: %s.',899 'an object with keys {' + Object.keys(refObject).join(', ') + '}',900 );901 }902 }903 const inst = create();904 refObject.current = inst;905 return () => {906 refObject.current = null;907 };908 }909}910function mountImperativeHandle<T>(911 ref: {|current: T | null|} | ((inst: T | null) => mixed) | null | void,912 create: () => T,913 deps: Array<mixed> | void | null,914): void {915 if (true) {916 if (typeof create !== 'function') {917 console.error(918 'Expected useImperativeHandle() second argument to be a function ' +919 'that creates a handle. Instead received: %s.',920 create !== null ? typeof create : 'null',921 );922 }923 }924 // TODO: If deps are provided, should we skip comparing the ref itself?925 const effectDeps =926 deps !== null && deps !== undefined ? deps.concat([ref]) : null;927 return mountEffectImpl(928 UpdateEffect,929 HookLayout,930 imperativeHandleEffect.bind(null, create, ref),931 effectDeps,932 );933}934function updateImperativeHandle<T>(935 ref: {|current: T | null|} | ((inst: T | null) => mixed) | null | void,936 create: () => T,937 deps: Array<mixed> | void | null,938): void {939 if (true) {940 if (typeof create !== 'function') {941 console.error(942 'Expected useImperativeHandle() second argument to be a function ' +943 'that creates a handle. Instead received: %s.',944 create !== null ? typeof create : 'null',945 );946 }947 }948 // TODO: If deps are provided, should we skip comparing the ref itself?949 const effectDeps =950 deps !== null && deps !== undefined ? deps.concat([ref]) : null;951 return updateEffectImpl(952 UpdateEffect,953 HookLayout,954 imperativeHandleEffect.bind(null, create, ref),955 effectDeps,956 );957}958function mountDebugValue<T>(value: T, formatterFn: ?(value: T) => mixed): void {959 // This hook is normally a no-op.960 // The react-debug-hooks package injects its own implementation961 // so that e.g. DevTools can display custom hook values.962}963const updateDebugValue = mountDebugValue;964function mountCallback<T>(callback: T, deps: Array<mixed> | void | null): T {965 const hook = mountWorkInProgressHook();966 const nextDeps = deps === undefined ? null : deps;967 hook.memoizedState = [callback, nextDeps];968 return callback;969}970function updateCallback<T>(callback: T, deps: Array<mixed> | void | null): T {971 const hook = updateWorkInProgressHook();972 const nextDeps = deps === undefined ? null : deps;973 const prevState = hook.memoizedState;974 if (prevState !== null) {975 if (nextDeps !== null) {976 const prevDeps: Array<mixed> | null = prevState[1];977 if (areHookInputsEqual(nextDeps, prevDeps)) {978 return prevState[0];979 }980 }981 }982 hook.memoizedState = [callback, nextDeps];983 return callback;984}985function mountMemo<T>(986 nextCreate: () => T,987 deps: Array<mixed> | void | null,988): T {989 const hook = mountWorkInProgressHook();990 const nextDeps = deps === undefined ? null : deps;991 const nextValue = nextCreate();992 hook.memoizedState = [nextValue, nextDeps];993 return nextValue;994}995function updateMemo<T>(996 nextCreate: () => T,997 deps: Array<mixed> | void | null,998): T {999 const hook = updateWorkInProgressHook();1000 const nextDeps = deps === undefined ? null : deps;1001 const prevState = hook.memoizedState;1002 if (prevState !== null) {1003 // Assume these are defined. If they're not, areHookInputsEqual will warn.1004 if (nextDeps !== null) {1005 const prevDeps: Array<mixed> | null = prevState[1];1006 if (areHookInputsEqual(nextDeps, prevDeps)) {1007 return prevState[0];1008 }1009 }1010 }1011 const nextValue = nextCreate();1012 hook.memoizedState = [nextValue, nextDeps];1013 return nextValue;1014}1015function mountDeferredValue<T>(1016 value: T,1017 config: TimeoutConfig | void | null,1018): T {1019 const [prevValue, setValue] = mountState(value);1020 mountEffect(() => {1021 const previousConfig = ReactCurrentBatchConfig.suspense;1022 ReactCurrentBatchConfig.suspense = config === undefined ? null : config;1023 try {1024 setValue(value);1025 } finally {1026 ReactCurrentBatchConfig.suspense = previousConfig;1027 }1028 }, [value, config]);1029 return prevValue;1030}1031function updateDeferredValue<T>(1032 value: T,1033 config: TimeoutConfig | void | null,1034): T {1035 const [prevValue, setValue] = updateState(value);1036 updateEffect(() => {1037 const previousConfig = ReactCurrentBatchConfig.suspense;1038 ReactCurrentBatchConfig.suspense = config === undefined ? null : config;1039 try {1040 setValue(value);1041 } finally {1042 ReactCurrentBatchConfig.suspense = previousConfig;1043 }1044 }, [value, config]);1045 return prevValue;1046}1047function rerenderDeferredValue<T>(1048 value: T,1049 config: TimeoutConfig | void | null,1050): T {1051 const [prevValue, setValue] = rerenderState(value);1052 updateEffect(() => {1053 const previousConfig = ReactCurrentBatchConfig.suspense;1054 ReactCurrentBatchConfig.suspense = config === undefined ? null : config;1055 try {1056 setValue(value);1057 } finally {1058 ReactCurrentBatchConfig.suspense = previousConfig;1059 }1060 }, [value, config]);1061 return prevValue;1062}1063function startTransition(setPending, config, callback) {1064 const priorityLevel = getCurrentPriorityLevel();1065 runWithPriority(1066 priorityLevel < UserBlockingPriority ? UserBlockingPriority : priorityLevel,1067 () => {1068 setPending(true);1069 },1070 );1071 runWithPriority(1072 priorityLevel > NormalPriority ? NormalPriority : priorityLevel,1073 () => {1074 const previousConfig = ReactCurrentBatchConfig.suspense;1075 ReactCurrentBatchConfig.suspense = config === undefined ? null : config;1076 try {1077 setPending(false);1078 callback();1079 } finally {1080 ReactCurrentBatchConfig.suspense = previousConfig;1081 }1082 },1083 );1084}1085function mountTransition(1086 config: SuspenseConfig | void | null,1087): [(() => void) => void, boolean] {1088 const [isPending, setPending] = mountState(false);1089 const start = mountCallback(startTransition.bind(null, setPending, config), [1090 setPending,1091 config,1092 ]);1093 return [start, isPending];1094}1095function updateTransition(1096 config: SuspenseConfig | void | null,1097): [(() => void) => void, boolean] {1098 const [isPending, setPending] = updateState(false);1099 const start = updateCallback(startTransition.bind(null, setPending, config), [1100 setPending,1101 config,1102 ]);1103 return [start, isPending];1104}1105function rerenderTransition(1106 config: SuspenseConfig | void | null,1107): [(() => void) => void, boolean] {1108 const [isPending, setPending] = rerenderState(false);1109 const start = updateCallback(startTransition.bind(null, setPending, config), [1110 setPending,1111 config,1112 ]);1113 return [start, isPending];1114}1115function dispatchAction<S, A>(1116 fiber: Fiber,1117 queue: UpdateQueue<S, A>,1118 action: A,1119) {1120 if (true) {1121 if (typeof arguments[3] === 'function') {1122 console.error(1123 "State updates from the useState() and useReducer() Hooks don't support the " +1124 'second callback argument. To execute a side effect after ' +1125 'rendering, declare it in the component body with useEffect().',1126 );1127 }1128 }1129 const currentTime = requestCurrentTimeForUpdate();1130 const suspenseConfig = requestCurrentSuspenseConfig();1131 const expirationTime = computeExpirationForFiber(1132 currentTime,1133 fiber,1134 suspenseConfig,1135 );1136 const update: Update<S, A> = {1137 expirationTime,1138 suspenseConfig,1139 action,1140 eagerReducer: null,1141 eagerState: null,1142 next: (null: any),1143 };1144 if (true) {1145 update.priority = getCurrentPriorityLevel();1146 }1147 // Append the update to the end of the list.1148 const pending = queue.pending;1149 if (pending === null) {1150 // This is the first update. Create a circular list.1151 update.next = update;1152 } else {1153 update.next = pending.next;1154 pending.next = update;1155 }1156 queue.pending = update;1157 const alternate = fiber.alternate;1158 if (1159 fiber === currentlyRenderingFiber ||1160 (alternate !== null && alternate === currentlyRenderingFiber)1161 ) {1162 // This is a render phase update. Stash it in a lazily-created map of1163 // queue -> linked list of updates. After this render pass, we'll restart1164 // and apply the stashed updates on top of the work-in-progress hook.1165 didScheduleRenderPhaseUpdate = true;1166 update.expirationTime = renderExpirationTime;1167 currentlyRenderingFiber.expirationTime = renderExpirationTime;1168 } else {1169 if (1170 fiber.expirationTime === NoWork &&1171 (alternate === null || alternate.expirationTime === NoWork)1172 ) {1173 // The queue is currently empty, which means we can eagerly compute the1174 // next state before entering the render phase. If the new state is the1175 // same as the current state, we may be able to bail out entirely.1176 const lastRenderedReducer = queue.lastRenderedReducer;1177 if (lastRenderedReducer !== null) {1178 let prevDispatcher;1179 if (true) {1180 prevDispatcher = ReactCurrentDispatcher.current;1181 ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnUpdateInDEV;1182 }1183 try {1184 const currentState: S = (queue.lastRenderedState: any);1185 const eagerState = lastRenderedReducer(currentState, action);1186 // Stash the eagerly computed state, and the reducer used to compute1187 // it, on the update object. If the reducer hasn't changed by the1188 // time we enter the render phase, then the eager state can be used1189 // without calling the reducer again.1190 update.eagerReducer = lastRenderedReducer;1191 update.eagerState = eagerState;1192 if (is(eagerState, currentState)) {1193 // Fast path. We can bail out without scheduling React to re-render.1194 // It's still possible that we'll need to rebase this update later,1195 // if the component re-renders for a different reason and by that1196 // time the reducer has changed.1197 return;1198 }1199 } catch (error) {1200 // Suppress the error. It will throw again in the render phase.1201 } finally {1202 if (true) {1203 ReactCurrentDispatcher.current = prevDispatcher;1204 }1205 }1206 }1207 }1208 if (true) {1209 // $FlowExpectedError - jest isn't a global, and isn't recognized outside of tests1210 if ('undefined' !== typeof jest) {1211 warnIfNotScopedWithMatchingAct(fiber);1212 warnIfNotCurrentlyActingUpdatesInDev(fiber);1213 }1214 }1215 scheduleWork(fiber, expirationTime);1216 }1217}1218export const ContextOnlyDispatcher: Dispatcher = {1219 readContext,1220 useCallback: throwInvalidHookError,1221 useContext: throwInvalidHookError,1222 useEffect: throwInvalidHookError,1223 useImperativeHandle: throwInvalidHookError,1224 useLayoutEffect: throwInvalidHookError,1225 useMemo: throwInvalidHookError,1226 useReducer: throwInvalidHookError,1227 useRef: throwInvalidHookError,1228 useState: throwInvalidHookError,1229 useDebugValue: throwInvalidHookError,1230 useResponder: throwInvalidHookError,1231 useDeferredValue: throwInvalidHookError,1232 useTransition: throwInvalidHookError,1233};1234const HooksDispatcherOnMount: Dispatcher = {1235 readContext,1236 useCallback: mountCallback,1237 useContext: readContext,1238 useEffect: mountEffect,1239 useImperativeHandle: mountImperativeHandle,1240 useLayoutEffect: mountLayoutEffect,1241 useMemo: mountMemo,1242 useReducer: mountReducer,1243 useRef: mountRef,1244 useState: mountState,1245 useDebugValue: mountDebugValue,1246 useResponder: createDeprecatedResponderListener,1247 useDeferredValue: mountDeferredValue,1248 useTransition: mountTransition,1249};1250const HooksDispatcherOnUpdate: Dispatcher = {1251 readContext,1252 useCallback: updateCallback,1253 useContext: readContext,1254 useEffect: updateEffect,1255 useImperativeHandle: updateImperativeHandle,1256 useLayoutEffect: updateLayoutEffect,1257 useMemo: updateMemo,1258 useReducer: updateReducer,1259 useRef: updateRef,1260 useState: updateState,1261 useDebugValue: updateDebugValue,1262 useResponder: createDeprecatedResponderListener,1263 useDeferredValue: updateDeferredValue,1264 useTransition: updateTransition,1265};1266const HooksDispatcherOnRerender: Dispatcher = {1267 readContext,1268 useCallback: updateCallback,1269 useContext: readContext,1270 useEffect: updateEffect,1271 useImperativeHandle: updateImperativeHandle,1272 useLayoutEffect: updateLayoutEffect,1273 useMemo: updateMemo,1274 useReducer: rerenderReducer,1275 useRef: updateRef,1276 useState: rerenderState,1277 useDebugValue: updateDebugValue,1278 useResponder: createDeprecatedResponderListener,1279 useDeferredValue: rerenderDeferredValue,1280 useTransition: rerenderTransition,1281};1282let HooksDispatcherOnMountInDEV: Dispatcher | null = null;1283let HooksDispatcherOnMountWithHookTypesInDEV: Dispatcher | null = null;1284let HooksDispatcherOnUpdateInDEV: Dispatcher | null = null;1285let HooksDispatcherOnRerenderInDEV: Dispatcher | null = null;1286let InvalidNestedHooksDispatcherOnMountInDEV: Dispatcher | null = null;1287let InvalidNestedHooksDispatcherOnUpdateInDEV: Dispatcher | null = null;1288let InvalidNestedHooksDispatcherOnRerenderInDEV: Dispatcher | null = null;1289if (true) {1290 const warnInvalidContextAccess = () => {1291 console.error(1292 'Context can only be read while React is rendering. ' +1293 'In classes, you can read it in the render method or getDerivedStateFromProps. ' +1294 'In function components, you can read it directly in the function body, but not ' +1295 'inside Hooks like useReducer() or useMemo().',1296 );1297 };1298 const warnInvalidHookAccess = () => {1299 console.error(1300 'Do not call Hooks inside useEffect(...), useMemo(...), or other built-in Hooks. ' +1301 'You can only call Hooks at the top level of your React function. ' +1302 'For more information, see ' +1303 'https://fb.me/rules-of-hooks',1304 );1305 };1306 HooksDispatcherOnMountInDEV = {1307 readContext<T>(1308 context: ReactContext<T>,1309 observedBits: void | number | boolean,1310 ): T {1311 return readContext(context, observedBits);1312 },1313 useCallback<T>(callback: T, deps: Array<mixed> | void | null): T {1314 currentHookNameInDev = 'useCallback';1315 mountHookTypesDev();1316 checkDepsAreArrayDev(deps);1317 return mountCallback(callback, deps);1318 },1319 useContext<T>(1320 context: ReactContext<T>,1321 observedBits: void | number | boolean,1322 ): T {1323 currentHookNameInDev = 'useContext';1324 mountHookTypesDev();1325 return readContext(context, observedBits);1326 },1327 useEffect(1328 create: () => (() => void) | void,1329 deps: Array<mixed> | void | null,1330 ): void {1331 currentHookNameInDev = 'useEffect';1332 mountHookTypesDev();1333 checkDepsAreArrayDev(deps);1334 return mountEffect(create, deps);1335 },1336 useImperativeHandle<T>(1337 ref: {|current: T | null|} | ((inst: T | null) => mixed) | null | void,1338 create: () => T,1339 deps: Array<mixed> | void | null,1340 ): void {1341 currentHookNameInDev = 'useImperativeHandle';1342 mountHookTypesDev();1343 checkDepsAreArrayDev(deps);1344 return mountImperativeHandle(ref, create, deps);1345 },1346 useLayoutEffect(1347 create: () => (() => void) | void,1348 deps: Array<mixed> | void | null,1349 ): void {1350 currentHookNameInDev = 'useLayoutEffect';1351 mountHookTypesDev();1352 checkDepsAreArrayDev(deps);1353 return mountLayoutEffect(create, deps);1354 },1355 useMemo<T>(create: () => T, deps: Array<mixed> | void | null): T {1356 currentHookNameInDev = 'useMemo';1357 mountHookTypesDev();1358 checkDepsAreArrayDev(deps);1359 const prevDispatcher = ReactCurrentDispatcher.current;1360 ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnMountInDEV;1361 try {1362 return mountMemo(create, deps);1363 } finally {1364 ReactCurrentDispatcher.current = prevDispatcher;1365 }1366 },1367 useReducer<S, I, A>(1368 reducer: (S, A) => S,1369 initialArg: I,1370 init?: I => S,1371 ): [S, Dispatch<A>] {1372 currentHookNameInDev = 'useReducer';1373 mountHookTypesDev();1374 const prevDispatcher = ReactCurrentDispatcher.current;1375 ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnMountInDEV;1376 try {1377 return mountReducer(reducer, initialArg, init);1378 } finally {1379 ReactCurrentDispatcher.current = prevDispatcher;1380 }1381 },1382 useRef<T>(initialValue: T): {|current: T|} {1383 currentHookNameInDev = 'useRef';1384 mountHookTypesDev();1385 return mountRef(initialValue);1386 },1387 useState<S>(1388 initialState: (() => S) | S,1389 ): [S, Dispatch<BasicStateAction<S>>] {1390 currentHookNameInDev = 'useState';1391 mountHookTypesDev();1392 const prevDispatcher = ReactCurrentDispatcher.current;1393 ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnMountInDEV;1394 try {1395 return mountState(initialState);1396 } finally {1397 ReactCurrentDispatcher.current = prevDispatcher;1398 }1399 },1400 useDebugValue<T>(value: T, formatterFn: ?(value: T) => mixed): void {1401 currentHookNameInDev = 'useDebugValue';1402 mountHookTypesDev();1403 return mountDebugValue(value, formatterFn);1404 },1405 useResponder<E, C>(1406 responder: ReactEventResponder<E, C>,1407 props,1408 ): ReactEventResponderListener<E, C> {1409 currentHookNameInDev = 'useResponder';1410 mountHookTypesDev();1411 return createDeprecatedResponderListener(responder, props);1412 },1413 useDeferredValue<T>(value: T, config: TimeoutConfig | void | null): T {1414 currentHookNameInDev = 'useDeferredValue';1415 mountHookTypesDev();1416 return mountDeferredValue(value, config);1417 },1418 useTransition(1419 config: SuspenseConfig | void | null,1420 ): [(() => void) => void, boolean] {1421 currentHookNameInDev = 'useTransition';1422 mountHookTypesDev();1423 return mountTransition(config);1424 },1425 };1426 HooksDispatcherOnMountWithHookTypesInDEV = {1427 readContext<T>(1428 context: ReactContext<T>,1429 observedBits: void | number | boolean,1430 ): T {1431 return readContext(context, observedBits);1432 },1433 useCallback<T>(callback: T, deps: Array<mixed> | void | null): T {1434 currentHookNameInDev = 'useCallback';1435 updateHookTypesDev();1436 return mountCallback(callback, deps);1437 },1438 useContext<T>(1439 context: ReactContext<T>,1440 observedBits: void | number | boolean,1441 ): T {1442 currentHookNameInDev = 'useContext';1443 updateHookTypesDev();1444 return readContext(context, observedBits);1445 },1446 useEffect(1447 create: () => (() => void) | void,1448 deps: Array<mixed> | void | null,1449 ): void {1450 currentHookNameInDev = 'useEffect';1451 updateHookTypesDev();1452 return mountEffect(create, deps);1453 },1454 useImperativeHandle<T>(1455 ref: {|current: T | null|} | ((inst: T | null) => mixed) | null | void,1456 create: () => T,1457 deps: Array<mixed> | void | null,1458 ): void {1459 currentHookNameInDev = 'useImperativeHandle';1460 updateHookTypesDev();1461 return mountImperativeHandle(ref, create, deps);1462 },1463 useLayoutEffect(1464 create: () => (() => void) | void,1465 deps: Array<mixed> | void | null,1466 ): void {1467 currentHookNameInDev = 'useLayoutEffect';1468 updateHookTypesDev();1469 return mountLayoutEffect(create, deps);1470 },1471 useMemo<T>(create: () => T, deps: Array<mixed> | void | null): T {1472 currentHookNameInDev = 'useMemo';1473 updateHookTypesDev();1474 const prevDispatcher = ReactCurrentDispatcher.current;1475 ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnMountInDEV;1476 try {1477 return mountMemo(create, deps);1478 } finally {1479 ReactCurrentDispatcher.current = prevDispatcher;1480 }1481 },1482 useReducer<S, I, A>(1483 reducer: (S, A) => S,1484 initialArg: I,1485 init?: I => S,1486 ): [S, Dispatch<A>] {1487 currentHookNameInDev = 'useReducer';1488 updateHookTypesDev();1489 const prevDispatcher = ReactCurrentDispatcher.current;1490 ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnMountInDEV;1491 try {1492 return mountReducer(reducer, initialArg, init);1493 } finally {1494 ReactCurrentDispatcher.current = prevDispatcher;1495 }1496 },1497 useRef<T>(initialValue: T): {|current: T|} {1498 currentHookNameInDev = 'useRef';1499 updateHookTypesDev();1500 return mountRef(initialValue);1501 },1502 useState<S>(1503 initialState: (() => S) | S,1504 ): [S, Dispatch<BasicStateAction<S>>] {1505 currentHookNameInDev = 'useState';1506 updateHookTypesDev();1507 const prevDispatcher = ReactCurrentDispatcher.current;1508 ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnMountInDEV;1509 try {1510 return mountState(initialState);1511 } finally {1512 ReactCurrentDispatcher.current = prevDispatcher;1513 }1514 },1515 useDebugValue<T>(value: T, formatterFn: ?(value: T) => mixed): void {1516 currentHookNameInDev = 'useDebugValue';1517 updateHookTypesDev();1518 return mountDebugValue(value, formatterFn);1519 },1520 useResponder<E, C>(1521 responder: ReactEventResponder<E, C>,1522 props,1523 ): ReactEventResponderListener<E, C> {1524 currentHookNameInDev = 'useResponder';1525 updateHookTypesDev();1526 return createDeprecatedResponderListener(responder, props);1527 },1528 useDeferredValue<T>(value: T, config: TimeoutConfig | void | null): T {1529 currentHookNameInDev = 'useDeferredValue';1530 updateHookTypesDev();1531 return mountDeferredValue(value, config);1532 },1533 useTransition(1534 config: SuspenseConfig | void | null,1535 ): [(() => void) => void, boolean] {1536 currentHookNameInDev = 'useTransition';1537 updateHookTypesDev();1538 return mountTransition(config);1539 },1540 };1541 HooksDispatcherOnUpdateInDEV = {1542 readContext<T>(1543 context: ReactContext<T>,1544 observedBits: void | number | boolean,1545 ): T {1546 return readContext(context, observedBits);1547 },1548 useCallback<T>(callback: T, deps: Array<mixed> | void | null): T {1549 currentHookNameInDev = 'useCallback';1550 updateHookTypesDev();1551 return updateCallback(callback, deps);1552 },1553 useContext<T>(1554 context: ReactContext<T>,1555 observedBits: void | number | boolean,1556 ): T {1557 currentHookNameInDev = 'useContext';1558 updateHookTypesDev();1559 return readContext(context, observedBits);1560 },1561 useEffect(1562 create: () => (() => void) | void,1563 deps: Array<mixed> | void | null,1564 ): void {1565 currentHookNameInDev = 'useEffect';1566 updateHookTypesDev();1567 return updateEffect(create, deps);1568 },1569 useImperativeHandle<T>(1570 ref: {|current: T | null|} | ((inst: T | null) => mixed) | null | void,1571 create: () => T,1572 deps: Array<mixed> | void | null,1573 ): void {1574 currentHookNameInDev = 'useImperativeHandle';1575 updateHookTypesDev();1576 return updateImperativeHandle(ref, create, deps);1577 },1578 useLayoutEffect(1579 create: () => (() => void) | void,1580 deps: Array<mixed> | void | null,1581 ): void {1582 currentHookNameInDev = 'useLayoutEffect';1583 updateHookTypesDev();1584 return updateLayoutEffect(create, deps);1585 },1586 useMemo<T>(create: () => T, deps: Array<mixed> | void | null): T {1587 currentHookNameInDev = 'useMemo';1588 updateHookTypesDev();1589 const prevDispatcher = ReactCurrentDispatcher.current;1590 ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnUpdateInDEV;1591 try {1592 return updateMemo(create, deps);1593 } finally {1594 ReactCurrentDispatcher.current = prevDispatcher;1595 }1596 },1597 useReducer<S, I, A>(1598 reducer: (S, A) => S,1599 initialArg: I,1600 init?: I => S,1601 ): [S, Dispatch<A>] {1602 currentHookNameInDev = 'useReducer';1603 updateHookTypesDev();1604 const prevDispatcher = ReactCurrentDispatcher.current;1605 ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnUpdateInDEV;1606 try {1607 return updateReducer(reducer, initialArg, init);1608 } finally {1609 ReactCurrentDispatcher.current = prevDispatcher;1610 }1611 },1612 useRef<T>(initialValue: T): {|current: T|} {1613 currentHookNameInDev = 'useRef';1614 updateHookTypesDev();1615 return updateRef(initialValue);1616 },1617 useState<S>(1618 initialState: (() => S) | S,1619 ): [S, Dispatch<BasicStateAction<S>>] {1620 currentHookNameInDev = 'useState';1621 updateHookTypesDev();1622 const prevDispatcher = ReactCurrentDispatcher.current;1623 ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnUpdateInDEV;1624 try {1625 return updateState(initialState);1626 } finally {1627 ReactCurrentDispatcher.current = prevDispatcher;1628 }1629 },1630 useDebugValue<T>(value: T, formatterFn: ?(value: T) => mixed): void {1631 currentHookNameInDev = 'useDebugValue';1632 updateHookTypesDev();1633 return updateDebugValue(value, formatterFn);1634 },1635 useResponder<E, C>(1636 responder: ReactEventResponder<E, C>,1637 props,1638 ): ReactEventResponderListener<E, C> {1639 currentHookNameInDev = 'useResponder';1640 updateHookTypesDev();1641 return createDeprecatedResponderListener(responder, props);1642 },1643 useDeferredValue<T>(value: T, config: TimeoutConfig | void | null): T {1644 currentHookNameInDev = 'useDeferredValue';1645 updateHookTypesDev();1646 return updateDeferredValue(value, config);1647 },1648 useTransition(1649 config: SuspenseConfig | void | null,1650 ): [(() => void) => void, boolean] {1651 currentHookNameInDev = 'useTransition';1652 updateHookTypesDev();1653 return updateTransition(config);1654 },1655 };1656 HooksDispatcherOnRerenderInDEV = {1657 readContext<T>(1658 context: ReactContext<T>,1659 observedBits: void | number | boolean,1660 ): T {1661 return readContext(context, observedBits);1662 },1663 useCallback<T>(callback: T, deps: Array<mixed> | void | null): T {1664 currentHookNameInDev = 'useCallback';1665 updateHookTypesDev();1666 return updateCallback(callback, deps);1667 },1668 useContext<T>(1669 context: ReactContext<T>,1670 observedBits: void | number | boolean,1671 ): T {1672 currentHookNameInDev = 'useContext';1673 updateHookTypesDev();1674 return readContext(context, observedBits);1675 },1676 useEffect(1677 create: () => (() => void) | void,1678 deps: Array<mixed> | void | null,1679 ): void {1680 currentHookNameInDev = 'useEffect';1681 updateHookTypesDev();1682 return updateEffect(create, deps);1683 },1684 useImperativeHandle<T>(1685 ref: {|current: T | null|} | ((inst: T | null) => mixed) | null | void,1686 create: () => T,1687 deps: Array<mixed> | void | null,1688 ): void {1689 currentHookNameInDev = 'useImperativeHandle';1690 updateHookTypesDev();1691 return updateImperativeHandle(ref, create, deps);1692 },1693 useLayoutEffect(1694 create: () => (() => void) | void,1695 deps: Array<mixed> | void | null,1696 ): void {1697 currentHookNameInDev = 'useLayoutEffect';1698 updateHookTypesDev();1699 return updateLayoutEffect(create, deps);1700 },1701 useMemo<T>(create: () => T, deps: Array<mixed> | void | null): T {1702 currentHookNameInDev = 'useMemo';1703 updateHookTypesDev();1704 const prevDispatcher = ReactCurrentDispatcher.current;1705 ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnRerenderInDEV;1706 try {1707 return updateMemo(create, deps);1708 } finally {1709 ReactCurrentDispatcher.current = prevDispatcher;1710 }1711 },1712 useReducer<S, I, A>(1713 reducer: (S, A) => S,1714 initialArg: I,1715 init?: I => S,1716 ): [S, Dispatch<A>] {1717 currentHookNameInDev = 'useReducer';1718 updateHookTypesDev();1719 const prevDispatcher = ReactCurrentDispatcher.current;1720 ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnRerenderInDEV;1721 try {1722 return rerenderReducer(reducer, initialArg, init);1723 } finally {1724 ReactCurrentDispatcher.current = prevDispatcher;1725 }1726 },1727 useRef<T>(initialValue: T): {|current: T|} {1728 currentHookNameInDev = 'useRef';1729 updateHookTypesDev();1730 return updateRef(initialValue);1731 },1732 useState<S>(1733 initialState: (() => S) | S,1734 ): [S, Dispatch<BasicStateAction<S>>] {1735 currentHookNameInDev = 'useState';1736 updateHookTypesDev();1737 const prevDispatcher = ReactCurrentDispatcher.current;1738 ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnRerenderInDEV;1739 try {1740 return rerenderState(initialState);1741 } finally {1742 ReactCurrentDispatcher.current = prevDispatcher;1743 }1744 },1745 useDebugValue<T>(value: T, formatterFn: ?(value: T) => mixed): void {1746 currentHookNameInDev = 'useDebugValue';1747 updateHookTypesDev();1748 return updateDebugValue(value, formatterFn);1749 },1750 useResponder<E, C>(1751 responder: ReactEventResponder<E, C>,1752 props,1753 ): ReactEventResponderListener<E, C> {1754 currentHookNameInDev = 'useResponder';1755 updateHookTypesDev();1756 return createDeprecatedResponderListener(responder, props);1757 },1758 useDeferredValue<T>(value: T, config: TimeoutConfig | void | null): T {1759 currentHookNameInDev = 'useDeferredValue';1760 updateHookTypesDev();1761 return rerenderDeferredValue(value, config);1762 },1763 useTransition(1764 config: SuspenseConfig | void | null,1765 ): [(() => void) => void, boolean] {1766 currentHookNameInDev = 'useTransition';1767 updateHookTypesDev();1768 return rerenderTransition(config);1769 },1770 };1771 InvalidNestedHooksDispatcherOnMountInDEV = {1772 readContext<T>(1773 context: ReactContext<T>,1774 observedBits: void | number | boolean,1775 ): T {1776 warnInvalidContextAccess();1777 return readContext(context, observedBits);1778 },1779 useCallback<T>(callback: T, deps: Array<mixed> | void | null): T {1780 currentHookNameInDev = 'useCallback';1781 warnInvalidHookAccess();1782 mountHookTypesDev();1783 return mountCallback(callback, deps);1784 },1785 useContext<T>(1786 context: ReactContext<T>,1787 observedBits: void | number | boolean,1788 ): T {1789 currentHookNameInDev = 'useContext';1790 warnInvalidHookAccess();1791 mountHookTypesDev();1792 return readContext(context, observedBits);1793 },1794 useEffect(1795 create: () => (() => void) | void,1796 deps: Array<mixed> | void | null,1797 ): void {1798 currentHookNameInDev = 'useEffect';1799 warnInvalidHookAccess();1800 mountHookTypesDev();1801 return mountEffect(create, deps);1802 },1803 useImperativeHandle<T>(1804 ref: {|current: T | null|} | ((inst: T | null) => mixed) | null | void,1805 create: () => T,1806 deps: Array<mixed> | void | null,1807 ): void {1808 currentHookNameInDev = 'useImperativeHandle';1809 warnInvalidHookAccess();1810 mountHookTypesDev();1811 return mountImperativeHandle(ref, create, deps);1812 },1813 useLayoutEffect(1814 create: () => (() => void) | void,1815 deps: Array<mixed> | void | null,1816 ): void {1817 currentHookNameInDev = 'useLayoutEffect';1818 warnInvalidHookAccess();1819 mountHookTypesDev();1820 return mountLayoutEffect(create, deps);1821 },1822 useMemo<T>(create: () => T, deps: Array<mixed> | void | null): T {1823 currentHookNameInDev = 'useMemo';1824 warnInvalidHookAccess();1825 mountHookTypesDev();1826 const prevDispatcher = ReactCurrentDispatcher.current;1827 ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnMountInDEV;1828 try {1829 return mountMemo(create, deps);1830 } finally {1831 ReactCurrentDispatcher.current = prevDispatcher;1832 }1833 },1834 useReducer<S, I, A>(1835 reducer: (S, A) => S,1836 initialArg: I,1837 init?: I => S,1838 ): [S, Dispatch<A>] {1839 currentHookNameInDev = 'useReducer';1840 warnInvalidHookAccess();1841 mountHookTypesDev();1842 const prevDispatcher = ReactCurrentDispatcher.current;1843 ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnMountInDEV;1844 try {1845 return mountReducer(reducer, initialArg, init);1846 } finally {1847 ReactCurrentDispatcher.current = prevDispatcher;1848 }1849 },1850 useRef<T>(initialValue: T): {|current: T|} {1851 currentHookNameInDev = 'useRef';1852 warnInvalidHookAccess();1853 mountHookTypesDev();1854 return mountRef(initialValue);1855 },1856 useState<S>(1857 initialState: (() => S) | S,1858 ): [S, Dispatch<BasicStateAction<S>>] {1859 currentHookNameInDev = 'useState';1860 warnInvalidHookAccess();1861 mountHookTypesDev();1862 const prevDispatcher = ReactCurrentDispatcher.current;1863 ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnMountInDEV;1864 try {1865 return mountState(initialState);1866 } finally {1867 ReactCurrentDispatcher.current = prevDispatcher;1868 }1869 },1870 useDebugValue<T>(value: T, formatterFn: ?(value: T) => mixed): void {1871 currentHookNameInDev = 'useDebugValue';1872 warnInvalidHookAccess();1873 mountHookTypesDev();1874 return mountDebugValue(value, formatterFn);1875 },1876 useResponder<E, C>(1877 responder: ReactEventResponder<E, C>,1878 props,1879 ): ReactEventResponderListener<E, C> {1880 currentHookNameInDev = 'useResponder';1881 warnInvalidHookAccess();1882 mountHookTypesDev();1883 return createDeprecatedResponderListener(responder, props);1884 },1885 useDeferredValue<T>(value: T, config: TimeoutConfig | void | null): T {1886 currentHookNameInDev = 'useDeferredValue';1887 warnInvalidHookAccess();1888 mountHookTypesDev();1889 return mountDeferredValue(value, config);1890 },1891 useTransition(1892 config: SuspenseConfig | void | null,1893 ): [(() => void) => void, boolean] {1894 currentHookNameInDev = 'useTransition';1895 warnInvalidHookAccess();1896 mountHookTypesDev();1897 return mountTransition(config);1898 },1899 };1900 InvalidNestedHooksDispatcherOnUpdateInDEV = {1901 readContext<T>(1902 context: ReactContext<T>,1903 observedBits: void | number | boolean,1904 ): T {1905 warnInvalidContextAccess();1906 return readContext(context, observedBits);1907 },1908 useCallback<T>(callback: T, deps: Array<mixed> | void | null): T {1909 currentHookNameInDev = 'useCallback';1910 warnInvalidHookAccess();...

Full Screen

Full Screen

Using AI Code Generation

copy

Full Screen

1const { mountHookTypesDev } = require('playwright');2mountHookTypesDev();3const { mountHookTypesDev } = require('playwright');4mountHookTypesDev();5const { mountHookTypesDev } = require('playwright');6mountHookTypesDev();7const { mountHookTypesDev } = require('playwright');8mountHookTypesDev();9const { mountHookTypesDev } = require('playwright');10mountHookTypesDev();11const { mountHookTypesDev } = require('playwright');12mountHookTypesDev();13const { mountHookTypesDev } = require('playwright');14mountHookTypesDev();15const { mountHookTypesDev } = require('playwright');16mountHookTypesDev();17const { mountHookTypesDev } = require('playwright');18mountHookTypesDev();19const { mountHookTypesDev } = require('playwright');20mountHookTypesDev();21const { mountHookTypesDev } = require('playwright');22mountHookTypesDev();23const { mountHookTypesDev } = require('playwright');24mountHookTypesDev();25const { mountHookTypesDev } = require('playwright');26mountHookTypesDev();27const { mountHookTypesDev } = require('playwright');28mountHookTypesDev();

Full Screen

Using AI Code Generation

copy

Full Screen

1const { mountHookTypesDev } = require('playwright/lib/server/trace/recorder');2const { chromium } = require('playwright');3const path = require('path');4(async () => {5 const browser = await chromium.launch();6 const context = await browser.newContext();7 await mountHookTypesDev(context, path.join(__dirname, 'hookTypes.json'));8 const page = await context.newPage();9 await page.screenshot({ path: 'example.png' });10 await browser.close();11})();12{ "hookTypes" : [ "beforeEach" , "beforeAll" , "afterEach" , "afterAll" ] }13import { PlaywrightTestConfig } from '@playwright/test';14const config: PlaywrightTestConfig = {15 use: {16 },17};18export default config;

Full Screen

Using AI Code Generation

copy

Full Screen

1const { mountHookTypesDev } = require('playwright-core/lib/server/registry');2const { chromium } = require('playwright-core');3const browser = await chromium.launch();4const page = await browser.newPage();5await mountHookTypesDev(page, {6 interface MyHook {7 name: string;8 }9});10await page.evaluate(() => {11 const hook = document.querySelector('my-hook');12});13await browser.close();14import { Page } from 'playwright-core';15import { mountHookTypesDev } from 'playwright-core/lib/server/registry';16declare module 'playwright-core/lib/server/registry' {17 export function mountHookTypesDev(18 options: {19 name: string;20 types: string;21 },22 ): Promise<void>;23}24const { chromium } = require('playwright-core');25(async () => {26 const browser = await chromium.launch();27 const page = await browser.newPage();28 await mountHookTypesDev(page, {29 interface MyHook {30 name: string;31 }32 });33 await page.evaluate(() => {34 const hook = document.querySelector('my-hook');35 });36 await browser.close();37})();38- `options: { name: string, types: string }`39- `options: { name: string, types: string }`40[MIT](

Full Screen

Using AI Code Generation

copy

Full Screen

1const { mountHookTypesDev } = require('@playwright/test/lib/server/devHookTypes');2mountHookTypesDev();3const { test } = require('@playwright/test');4test('example test', async ({ page }) => {5});6{7 "compilerOptions": {8 },9}10import { test } from '@playwright/test';11test('example test', async ({ page }) => {12});13{14 "scripts": {15 }16}17{18 {19 "targets": {20 }21 }22}

Full Screen

Using AI Code Generation

copy

Full Screen

1const { mountHookTypesDev } = require("@playwright/test/lib/server/devtoolsServer");2const { launchServer } = require("@playwright/test/lib/server/processLauncher");3const server = await launchServer({4 env: {5 },6});7await mountHookTypesDev(server);8const browser = await chromium.connectOverCDP({9});10const context = await browser.newContext();11const page = await context.newPage();12const element = await page.$("text=Get started");13await element.click();14await browser.close();15await server.close();16await context.close();17await page.close();18await page.stopTracing();19await page.stopScreencast();20await page.stopHar();21await page.stopCoverage();22await browser.close();23await server.close();24await context.close();25await page.close();26await page.stopTracing();

Full Screen

Using AI Code Generation

copy

Full Screen

1const { mountHookTypesDev } = require('playwright/lib/server/trace/recorder/hookTypes');2const { hookTypes, hookTypeNames } = require('playwright/lib/server/trace/recorder/hookTypes');3const { assert } = require('playwright/lib/utils/utils');4(async () => {5 const hookTypes = await mountHookTypesDev();6 assert(hookTypes.length === hookTypeNames.length);7 for (const [index, hookType] of hookTypeNames.entries())8 assert(hookTypes[index] === hookType);9})();10];

Full Screen

Using AI Code Generation

copy

Full Screen

1const { mountHookTypesDev } = require('playwright');2mountHookTypesDev();3const { test } = require('@playwright/test');4test('test', async ({ page }) => {5});6const { test } = require('@playwright/test');7test('test', async ({ page }) => {8});9const { test } = require('@playwright/test');10test('test', async ({ page }) => {11});12const { test } = require('@playwright/test');13test('test', async ({ page }) => {14});15const { test } = require('@playwright/test');16test('test', async ({ page }) => {17});18const { test } = require('@playwright/test');19test('test', async ({ page }) => {20});21const { test } = require('@playwright/test');22test('test', async ({ page }) => {23});24const { test } = require('@playwright/test');25test('test', async ({ page }) => {26});27const { test } = require('@playwright/test');28test('test', async ({ page }) => {29});30const { test } = require('@playwright/test');31test('test', async ({ page }) => {

Full Screen

Playwright tutorial

LambdaTest’s Playwright tutorial will give you a broader idea about the Playwright automation framework, its unique features, and use cases with examples to exceed your understanding of Playwright testing. This tutorial will give A to Z guidance, from installing the Playwright framework to some best practices and advanced concepts.

Chapters:

  1. What is Playwright : Playwright is comparatively new but has gained good popularity. Get to know some history of the Playwright with some interesting facts connected with it.
  2. How To Install Playwright : Learn in detail about what basic configuration and dependencies are required for installing Playwright and run a test. Get a step-by-step direction for installing the Playwright automation framework.
  3. Playwright Futuristic Features: Launched in 2020, Playwright gained huge popularity quickly because of some obliging features such as Playwright Test Generator and Inspector, Playwright Reporter, Playwright auto-waiting mechanism and etc. Read up on those features to master Playwright testing.
  4. What is Component Testing: Component testing in Playwright is a unique feature that allows a tester to test a single component of a web application without integrating them with other elements. Learn how to perform Component testing on the Playwright automation framework.
  5. Inputs And Buttons In Playwright: Every website has Input boxes and buttons; learn about testing inputs and buttons with different scenarios and examples.
  6. Functions and Selectors in Playwright: Learn how to launch the Chromium browser with Playwright. Also, gain a better understanding of some important functions like “BrowserContext,” which allows you to run multiple browser sessions, and “newPage” which interacts with a page.
  7. Handling Alerts and Dropdowns in Playwright : Playwright interact with different types of alerts and pop-ups, such as simple, confirmation, and prompt, and different types of dropdowns, such as single selector and multi-selector get your hands-on with handling alerts and dropdown in Playright testing.
  8. Playwright vs Puppeteer: Get to know about the difference between two testing frameworks and how they are different than one another, which browsers they support, and what features they provide.
  9. Run Playwright Tests on LambdaTest: Playwright testing with LambdaTest leverages test performance to the utmost. You can run multiple Playwright tests in Parallel with the LammbdaTest test cloud. Get a step-by-step guide to run your Playwright test on the LambdaTest platform.
  10. Playwright Python Tutorial: Playwright automation framework support all major languages such as Python, JavaScript, TypeScript, .NET and etc. However, there are various advantages to Python end-to-end testing with Playwright because of its versatile utility. Get the hang of Playwright python testing with this chapter.
  11. Playwright End To End Testing Tutorial: Get your hands on with Playwright end-to-end testing and learn to use some exciting features such as TraceViewer, Debugging, Networking, Component testing, Visual testing, and many more.
  12. Playwright Video Tutorial: Watch the video tutorials on Playwright testing from experts and get a consecutive in-depth explanation of Playwright automation testing.

Run Playwright Internal automation tests on LambdaTest cloud grid

Perform automation testing on 3000+ real desktop and mobile devices online.

Try LambdaTest Now !!

Get 100 minutes of automation test minutes FREE!!

Next-Gen App & Browser Testing Cloud

Was this article helpful?

Helpful

NotHelpful