Best JavaScript code snippet using playwright-internal
ReactFiberWorkLoop.js
Source:ReactFiberWorkLoop.js
...2614 );2615 }2616 }2617}2618function warnIfNotCurrentlyActingUpdatesInDEV(fiber: Fiber): void {2619 if (true) {2620 if (2621 warnsIfNotActing === true &&2622 executionContext === NoContext &&2623 IsSomeRendererActing.current === false &&2624 IsThisRendererActing.current === false2625 ) {2626 console.error(2627 'An update to %s inside a test was not wrapped in act(...).\n\n' +2628 'When testing, code that causes React state updates should be ' +2629 'wrapped into act(...):\n\n' +2630 'act(() => {\n' +2631 ' /* fire events that update state */\n' +2632 '});\n' +...
ReactFiberWorkLoop.old.js
Source:ReactFiberWorkLoop.old.js
...2052 error('An update to %s ran an effect, but was not wrapped in act(...).\n\n' + 'When testing, code that causes React state updates should be ' + 'wrapped into act(...):\n\n' + 'act(() => {\n' + ' /* fire events that update state */\n' + '});\n' + '/* assert on the output */\n\n' + "This ensures that you're testing the behavior the user would see " + 'in the browser.' + ' Learn more at https://reactjs.org/link/wrap-tests-with-act', getComponentName(fiber.type));2053 }2054 }2055 }2056 function warnIfNotCurrentlyActingUpdatesInDEV(fiber) {2057 {2058 if ( executionContext === NoContext && IsSomeRendererActing.current === false && IsThisRendererActing.current === false) {2059 var previousFiber = current;2060 try {2061 setCurrentFiber(fiber);2062 error('An update to %s inside a test was not wrapped in act(...).\n\n' + 'When testing, code that causes React state updates should be ' + 'wrapped into act(...):\n\n' + 'act(() => {\n' + ' /* fire events that update state */\n' + '});\n' + '/* assert on the output */\n\n' + "This ensures that you're testing the behavior the user would see " + 'in the browser.' + ' Learn more at https://reactjs.org/link/wrap-tests-with-act', getComponentName(fiber.type));2063 } finally {2064 if (previousFiber) {2065 setCurrentFiber(fiber);2066 } else {2067 resetCurrentFiber();2068 }2069 }2070 }...
ReactFiberScheduler.new.js
Source:ReactFiberScheduler.new.js
...1850 }1851 }1852 }1853}1854function warnIfNotCurrentlyActingUpdatesInDEV(fiber: Fiber): void {1855 if (__DEV__) {1856 if (1857 workPhase === NotWorking &&1858 ReactShouldWarnActingUpdates.current === false1859 ) {1860 warningWithoutStack(1861 false,1862 'An update to %s inside a test was not wrapped in act(...).\n\n' +1863 'When testing, code that causes React state updates should be ' +1864 'wrapped into act(...):\n\n' +1865 'act(() => {\n' +1866 ' /* fire events that update state */\n' +1867 '});\n' +1868 '/* assert on the output */\n\n' +...
ReactFiberHooks.js
Source:ReactFiberHooks.js
1/**2 * Copyright (c) Facebook, Inc. and its affiliates.3 *4 * This source code is licensed under the MIT license found in the5 * LICENSE file in the root directory of this source tree.6 *7 * @flow8 */9import type {ReactContext} from 'shared/ReactTypes';10import type {SideEffectTag} from 'shared/ReactSideEffectTags';11import type {Fiber} from './ReactFiber';12import type {ExpirationTime} from './ReactFiberExpirationTime';13import type {HookEffectTag} from './ReactHookEffectTags';14import ReactSharedInternals from 'shared/ReactSharedInternals';15import {NoWork} from './ReactFiberExpirationTime';16import {readContext} from './ReactFiberNewContext';17import {18 Update as UpdateEffect,19 Passive as PassiveEffect,20} from 'shared/ReactSideEffectTags';21import {22 NoEffect as NoHookEffect,23 UnmountMutation,24 MountLayout,25 UnmountPassive,26 MountPassive,27} from './ReactHookEffectTags';28import {29 scheduleWork,30 computeExpirationForFiber,31 flushPassiveEffects,32 requestCurrentTime,33 warnIfNotCurrentlyActingUpdatesInDev,34 markRenderEventTime,35} from './ReactFiberScheduler';36import invariant from 'shared/invariant';37import warning from 'shared/warning';38import getComponentName from 'shared/getComponentName';39import is from 'shared/objectIs';40import {markWorkInProgressReceivedUpdate} from './ReactFiberBeginWork';41const {ReactCurrentDispatcher} = ReactSharedInternals;42export type Dispatcher = {43 readContext<T>(44 context: ReactContext<T>,45 observedBits: void | number | boolean,46 ): T,47 useState<S>(initialState: (() => S) | S): [S, Dispatch<BasicStateAction<S>>],48 useReducer<S, I, A>(49 reducer: (S, A) => S,50 initialArg: I,51 init?: (I) => S,52 ): [S, Dispatch<A>],53 useContext<T>(54 context: ReactContext<T>,55 observedBits: void | number | boolean,56 ): T,57 useRef<T>(initialValue: T): {current: T},58 useEffect(59 create: () => (() => void) | void,60 deps: Array<mixed> | void | null,61 ): void,62 useLayoutEffect(63 create: () => (() => void) | void,64 deps: Array<mixed> | void | null,65 ): void,66 useCallback<T>(callback: T, deps: Array<mixed> | void | null): T,67 useMemo<T>(nextCreate: () => T, deps: Array<mixed> | void | null): T,68 useImperativeHandle<T>(69 ref: {current: T | null} | ((inst: T | null) => mixed) | null | void,70 create: () => T,71 deps: Array<mixed> | void | null,72 ): void,73 useDebugValue<T>(value: T, formatterFn: ?(value: T) => mixed): void,74};75type Update<S, A> = {76 expirationTime: ExpirationTime,77 action: A,78 eagerReducer: ((S, A) => S) | null,79 eagerState: S | null,80 next: Update<S, A> | null,81};82type UpdateQueue<S, A> = {83 last: Update<S, A> | null,84 dispatch: (A => mixed) | null,85 lastRenderedReducer: ((S, A) => S) | null,86 lastRenderedState: S | null,87};88export type HookType =89 | 'useState'90 | 'useReducer'91 | 'useContext'92 | 'useRef'93 | 'useEffect'94 | 'useLayoutEffect'95 | 'useCallback'96 | 'useMemo'97 | 'useImperativeHandle'98 | 'useDebugValue';99let didWarnAboutMismatchedHooksForComponent;100if (__DEV__) {101 didWarnAboutMismatchedHooksForComponent = new Set();102}103export type Hook = {104 memoizedState: any,105 baseState: any,106 baseUpdate: Update<any, any> | null,107 queue: UpdateQueue<any, any> | null,108 next: Hook | null,109};110type Effect = {111 tag: HookEffectTag,112 create: () => (() => void) | void,113 destroy: (() => void) | void,114 deps: Array<mixed> | null,115 next: Effect,116};117export type FunctionComponentUpdateQueue = {118 lastEffect: Effect | null,119};120type BasicStateAction<S> = (S => S) | S;121type Dispatch<A> = A => void;122// These are set right before calling the component.123let renderExpirationTime: ExpirationTime = NoWork;124// The work-in-progress fiber. I've named it differently to distinguish it from125// the work-in-progress hook.126let currentlyRenderingFiber: Fiber | null = null;127// Hooks are stored as a linked list on the fiber's memoizedState field. The128// current hook list is the list that belongs to the current fiber. The129// work-in-progress hook list is a new list that will be added to the130// work-in-progress fiber.131let currentHook: Hook | null = null;132let nextCurrentHook: Hook | null = null;133let firstWorkInProgressHook: Hook | null = null;134let workInProgressHook: Hook | null = null;135let nextWorkInProgressHook: Hook | null = null;136let remainingExpirationTime: ExpirationTime = NoWork;137let componentUpdateQueue: FunctionComponentUpdateQueue | null = null;138let sideEffectTag: SideEffectTag = 0;139// Updates scheduled during render will trigger an immediate re-render at the140// end of the current pass. We can't store these updates on the normal queue,141// because if the work is aborted, they should be discarded. Because this is142// a relatively rare case, we also don't want to add an additional field to143// either the hook or queue object types. So we store them in a lazily create144// map of queue -> render-phase updates, which are discarded once the component145// completes without re-rendering.146// Whether an update was scheduled during the currently executing render pass.147let didScheduleRenderPhaseUpdate: boolean = false;148// Lazily created map of render-phase updates149let renderPhaseUpdates: Map<150 UpdateQueue<any, any>,151 Update<any, any>,152> | null = null;153// Counter to prevent infinite loops.154let numberOfReRenders: number = 0;155const RE_RENDER_LIMIT = 25;156// In DEV, this is the name of the currently executing primitive hook157let currentHookNameInDev: ?HookType = null;158// In DEV, this list ensures that hooks are called in the same order between renders.159// The list stores the order of hooks used during the initial render (mount).160// Subsequent renders (updates) reference this list.161let hookTypesDev: Array<HookType> | null = null;162let hookTypesUpdateIndexDev: number = -1;163function mountHookTypesDev() {164 if (__DEV__) {165 const hookName = ((currentHookNameInDev: any): HookType);166 if (hookTypesDev === null) {167 hookTypesDev = [hookName];168 } else {169 hookTypesDev.push(hookName);170 }171 }172}173function updateHookTypesDev() {174 if (__DEV__) {175 const hookName = ((currentHookNameInDev: any): HookType);176 if (hookTypesDev !== null) {177 hookTypesUpdateIndexDev++;178 if (hookTypesDev[hookTypesUpdateIndexDev] !== hookName) {179 warnOnHookMismatchInDev(hookName);180 }181 }182 }183}184function checkDepsAreArrayDev(deps: mixed) {185 if (__DEV__) {186 if (deps !== undefined && deps !== null && !Array.isArray(deps)) {187 // Verify deps, but only on mount to avoid extra checks.188 // It's unlikely their type would change as usually you define them inline.189 warning(190 false,191 '%s received a final argument that is not an array (instead, received `%s`). When ' +192 'specified, the final argument must be an array.',193 currentHookNameInDev,194 typeof deps,195 );196 }197 }198}199function warnOnHookMismatchInDev(currentHookName: HookType) {200 if (__DEV__) {201 const componentName = getComponentName(202 ((currentlyRenderingFiber: any): Fiber).type,203 );204 if (!didWarnAboutMismatchedHooksForComponent.has(componentName)) {205 didWarnAboutMismatchedHooksForComponent.add(componentName);206 if (hookTypesDev !== null) {207 let table = '';208 const secondColumnStart = 30;209 for (let i = 0; i <= ((hookTypesUpdateIndexDev: any): number); i++) {210 const oldHookName = hookTypesDev[i];211 const newHookName =212 i === ((hookTypesUpdateIndexDev: any): number)213 ? currentHookName214 : oldHookName;215 let row = `${i + 1}. ${oldHookName}`;216 // Extra space so second column lines up217 // lol @ IE not supporting String#repeat218 while (row.length < secondColumnStart) {219 row += ' ';220 }221 row += newHookName + '\n';222 table += row;223 }224 warning(225 false,226 'React has detected a change in the order of Hooks called by %s. ' +227 'This will lead to bugs and errors if not fixed. ' +228 'For more information, read the Rules of Hooks: https://fb.me/rules-of-hooks\n\n' +229 ' Previous render Next render\n' +230 ' ------------------------------------------------------\n' +231 '%s' +232 ' ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n',233 componentName,234 table,235 );236 }237 }238 }239}240function throwInvalidHookError() {241 invariant(242 false,243 'Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for' +244 ' one of the following reasons:\n' +245 '1. You might have mismatching versions of React and the renderer (such as React DOM)\n' +246 '2. You might be breaking the Rules of Hooks\n' +247 '3. You might have more than one copy of React in the same app\n' +248 'See https://fb.me/react-invalid-hook-call for tips about how to debug and fix this problem.',249 );250}251function areHookInputsEqual(252 nextDeps: Array<mixed>,253 prevDeps: Array<mixed> | null,254) {255 if (prevDeps === null) {256 if (__DEV__) {257 warning(258 false,259 '%s received a final argument during this render, but not during ' +260 'the previous render. Even though the final argument is optional, ' +261 'its type cannot change between renders.',262 currentHookNameInDev,263 );264 }265 return false;266 }267 if (__DEV__) {268 // Don't bother comparing lengths in prod because these arrays should be269 // passed inline.270 if (nextDeps.length !== prevDeps.length) {271 warning(272 false,273 'The final argument passed to %s changed size between renders. The ' +274 'order and size of this array must remain constant.\n\n' +275 'Previous: %s\n' +276 'Incoming: %s',277 currentHookNameInDev,278 `[${prevDeps.join(', ')}]`,279 `[${nextDeps.join(', ')}]`,280 );281 }282 }283 for (let i = 0; i < prevDeps.length && i < nextDeps.length; i++) {284 if (is(nextDeps[i], prevDeps[i])) {285 continue;286 }287 return false;288 }289 return true;290}291export function renderWithHooks(292 current: Fiber | null,293 workInProgress: Fiber,294 Component: any,295 props: any,296 refOrContext: any,297 nextRenderExpirationTime: ExpirationTime,298): any {299 renderExpirationTime = nextRenderExpirationTime;300 currentlyRenderingFiber = workInProgress;301 nextCurrentHook = current !== null ? current.memoizedState : null;302 if (__DEV__) {303 hookTypesDev =304 current !== null305 ? ((current._debugHookTypes: any): Array<HookType>)306 : null;307 hookTypesUpdateIndexDev = -1;308 }309 // The following should have already been reset310 // currentHook = null;311 // workInProgressHook = null;312 // remainingExpirationTime = NoWork;313 // componentUpdateQueue = null;314 // didScheduleRenderPhaseUpdate = false;315 // renderPhaseUpdates = null;316 // numberOfReRenders = 0;317 // sideEffectTag = 0;318 // TODO Warn if no hooks are used at all during mount, then some are used during update.319 // Currently we will identify the update render as a mount because nextCurrentHook === null.320 // This is tricky because it's valid for certain types of components (e.g. React.lazy)321 // Using nextCurrentHook to differentiate between mount/update only works if at least one stateful hook is used.322 // Non-stateful hooks (e.g. context) don't get added to memoizedState,323 // so nextCurrentHook would be null during updates and mounts.324 if (__DEV__) {325 if (nextCurrentHook !== null) {326 ReactCurrentDispatcher.current = HooksDispatcherOnUpdateInDEV;327 } else if (hookTypesDev !== null) {328 // This dispatcher handles an edge case where a component is updating,329 // but no stateful hooks have been used.330 // We want to match the production code behavior (which will use HooksDispatcherOnMount),331 // but with the extra DEV validation to ensure hooks ordering hasn't changed.332 // This dispatcher does that.333 ReactCurrentDispatcher.current = HooksDispatcherOnMountWithHookTypesInDEV;334 } else {335 ReactCurrentDispatcher.current = HooksDispatcherOnMountInDEV;336 }337 } else {338 ReactCurrentDispatcher.current =339 nextCurrentHook === null340 ? HooksDispatcherOnMount341 : HooksDispatcherOnUpdate;342 }343 let children = Component(props, refOrContext);344 if (didScheduleRenderPhaseUpdate) {345 do {346 didScheduleRenderPhaseUpdate = false;347 numberOfReRenders += 1;348 // Start over from the beginning of the list349 nextCurrentHook = current !== null ? current.memoizedState : null;350 nextWorkInProgressHook = firstWorkInProgressHook;351 currentHook = null;352 workInProgressHook = null;353 componentUpdateQueue = null;354 if (__DEV__) {355 // Also validate hook order for cascading updates.356 hookTypesUpdateIndexDev = -1;357 }358 ReactCurrentDispatcher.current = __DEV__359 ? HooksDispatcherOnUpdateInDEV360 : HooksDispatcherOnUpdate;361 children = Component(props, refOrContext);362 } while (didScheduleRenderPhaseUpdate);363 renderPhaseUpdates = null;364 numberOfReRenders = 0;365 }366 // We can assume the previous dispatcher is always this one, since we set it367 // at the beginning of the render phase and there's no re-entrancy.368 ReactCurrentDispatcher.current = ContextOnlyDispatcher;369 const renderedWork: Fiber = (currentlyRenderingFiber: any);370 renderedWork.memoizedState = firstWorkInProgressHook;371 renderedWork.expirationTime = remainingExpirationTime;372 renderedWork.updateQueue = (componentUpdateQueue: any);373 renderedWork.effectTag |= sideEffectTag;374 if (__DEV__) {375 renderedWork._debugHookTypes = hookTypesDev;376 }377 // This check uses currentHook so that it works the same in DEV and prod bundles.378 // hookTypesDev could catch more cases (e.g. context) but only in DEV bundles.379 const didRenderTooFewHooks =380 currentHook !== null && currentHook.next !== null;381 renderExpirationTime = NoWork;382 currentlyRenderingFiber = null;383 currentHook = null;384 nextCurrentHook = null;385 firstWorkInProgressHook = null;386 workInProgressHook = null;387 nextWorkInProgressHook = null;388 if (__DEV__) {389 currentHookNameInDev = null;390 hookTypesDev = null;391 hookTypesUpdateIndexDev = -1;392 }393 remainingExpirationTime = NoWork;394 componentUpdateQueue = null;395 sideEffectTag = 0;396 // These were reset above397 // didScheduleRenderPhaseUpdate = false;398 // renderPhaseUpdates = null;399 // numberOfReRenders = 0;400 invariant(401 !didRenderTooFewHooks,402 'Rendered fewer hooks than expected. This may be caused by an accidental ' +403 'early return statement.',404 );405 return children;406}407export function bailoutHooks(408 current: Fiber,409 workInProgress: Fiber,410 expirationTime: ExpirationTime,411) {412 workInProgress.updateQueue = current.updateQueue;413 workInProgress.effectTag &= ~(PassiveEffect | UpdateEffect);414 if (current.expirationTime <= expirationTime) {415 current.expirationTime = NoWork;416 }417}418export function resetHooks(): void {419 // We can assume the previous dispatcher is always this one, since we set it420 // at the beginning of the render phase and there's no re-entrancy.421 ReactCurrentDispatcher.current = ContextOnlyDispatcher;422 // This is used to reset the state of this module when a component throws.423 // It's also called inside mountIndeterminateComponent if we determine the424 // component is a module-style component.425 renderExpirationTime = NoWork;426 currentlyRenderingFiber = null;427 currentHook = null;428 nextCurrentHook = null;429 firstWorkInProgressHook = null;430 workInProgressHook = null;431 nextWorkInProgressHook = null;432 if (__DEV__) {433 hookTypesDev = null;434 hookTypesUpdateIndexDev = -1;435 currentHookNameInDev = null;436 }437 remainingExpirationTime = NoWork;438 componentUpdateQueue = null;439 sideEffectTag = 0;440 didScheduleRenderPhaseUpdate = false;441 renderPhaseUpdates = null;442 numberOfReRenders = 0;443}444function mountWorkInProgressHook(): Hook {445 const hook: Hook = {446 memoizedState: null,447 baseState: null,448 queue: null,449 baseUpdate: null,450 next: null,451 };452 if (workInProgressHook === null) {453 // This is the first hook in the list454 firstWorkInProgressHook = workInProgressHook = hook;455 } else {456 // Append to the end of the list457 workInProgressHook = workInProgressHook.next = hook;458 }459 return workInProgressHook;460}461function updateWorkInProgressHook(): Hook {462 // This function is used both for updates and for re-renders triggered by a463 // render phase update. It assumes there is either a current hook we can464 // clone, or a work-in-progress hook from a previous render pass that we can465 // use as a base. When we reach the end of the base list, we must switch to466 // the dispatcher used for mounts.467 if (nextWorkInProgressHook !== null) {468 // There's already a work-in-progress. Reuse it.469 workInProgressHook = nextWorkInProgressHook;470 nextWorkInProgressHook = workInProgressHook.next;471 currentHook = nextCurrentHook;472 nextCurrentHook = currentHook !== null ? currentHook.next : null;473 } else {474 // Clone from the current hook.475 invariant(476 nextCurrentHook !== null,477 'Rendered more hooks than during the previous render.',478 );479 currentHook = nextCurrentHook;480 const newHook: Hook = {481 memoizedState: currentHook.memoizedState,482 baseState: currentHook.baseState,483 queue: currentHook.queue,484 baseUpdate: currentHook.baseUpdate,485 next: null,486 };487 if (workInProgressHook === null) {488 // This is the first hook in the list.489 workInProgressHook = firstWorkInProgressHook = newHook;490 } else {491 // Append to the end of the list.492 workInProgressHook = workInProgressHook.next = newHook;493 }494 nextCurrentHook = currentHook.next;495 }496 return workInProgressHook;497}498function createFunctionComponentUpdateQueue(): FunctionComponentUpdateQueue {499 return {500 lastEffect: null,501 };502}503function basicStateReducer<S>(state: S, action: BasicStateAction<S>): S {504 return typeof action === 'function' ? action(state) : action;505}506function mountReducer<S, I, A>(507 reducer: (S, A) => S,508 initialArg: I,509 init?: I => S,510): [S, Dispatch<A>] {511 const hook = mountWorkInProgressHook();512 let initialState;513 if (init !== undefined) {514 initialState = init(initialArg);515 } else {516 initialState = ((initialArg: any): S);517 }518 hook.memoizedState = hook.baseState = initialState;519 const queue = (hook.queue = {520 last: null,521 dispatch: null,522 lastRenderedReducer: reducer,523 lastRenderedState: (initialState: any),524 });525 const dispatch: Dispatch<A> = (queue.dispatch = (dispatchAction.bind(526 null,527 // Flow doesn't know this is non-null, but we do.528 ((currentlyRenderingFiber: any): Fiber),529 queue,530 ): any));531 return [hook.memoizedState, dispatch];532}533function updateReducer<S, I, A>(534 reducer: (S, A) => S,535 initialArg: I,536 init?: I => S,537): [S, Dispatch<A>] {538 const hook = updateWorkInProgressHook();539 const queue = hook.queue;540 invariant(541 queue !== null,542 'Should have a queue. This is likely a bug in React. Please file an issue.',543 );544 queue.lastRenderedReducer = reducer;545 if (numberOfReRenders > 0) {546 // This is a re-render. Apply the new render phase updates to the previous547 // work-in-progress hook.548 const dispatch: Dispatch<A> = (queue.dispatch: any);549 if (renderPhaseUpdates !== null) {550 // Render phase updates are stored in a map of queue -> linked list551 const firstRenderPhaseUpdate = renderPhaseUpdates.get(queue);552 if (firstRenderPhaseUpdate !== undefined) {553 renderPhaseUpdates.delete(queue);554 let newState = hook.memoizedState;555 let update = firstRenderPhaseUpdate;556 do {557 // Process this render phase update. We don't have to check the558 // priority because it will always be the same as the current559 // render's.560 const action = update.action;561 newState = reducer(newState, action);562 update = update.next;563 } while (update !== null);564 // Mark that the fiber performed work, but only if the new state is565 // different from the current state.566 if (!is(newState, hook.memoizedState)) {567 markWorkInProgressReceivedUpdate();568 }569 hook.memoizedState = newState;570 // Don't persist the state accumlated from the render phase updates to571 // the base state unless the queue is empty.572 // TODO: Not sure if this is the desired semantics, but it's what we573 // do for gDSFP. I can't remember why.574 if (hook.baseUpdate === queue.last) {575 hook.baseState = newState;576 }577 queue.lastRenderedState = newState;578 return [newState, dispatch];579 }580 }581 return [hook.memoizedState, dispatch];582 }583 // The last update in the entire queue584 const last = queue.last;585 // The last update that is part of the base state.586 const baseUpdate = hook.baseUpdate;587 const baseState = hook.baseState;588 // Find the first unprocessed update.589 let first;590 if (baseUpdate !== null) {591 if (last !== null) {592 // For the first update, the queue is a circular linked list where593 // `queue.last.next = queue.first`. Once the first update commits, and594 // the `baseUpdate` is no longer empty, we can unravel the list.595 last.next = null;596 }597 first = baseUpdate.next;598 } else {599 first = last !== null ? last.next : null;600 }601 if (first !== null) {602 let newState = baseState;603 let newBaseState = null;604 let newBaseUpdate = null;605 let prevUpdate = baseUpdate;606 let update = first;607 let didSkip = false;608 do {609 const updateExpirationTime = update.expirationTime;610 if (updateExpirationTime < renderExpirationTime) {611 // Priority is insufficient. Skip this update. If this is the first612 // skipped update, the previous update/state is the new base613 // update/state.614 if (!didSkip) {615 didSkip = true;616 newBaseUpdate = prevUpdate;617 newBaseState = newState;618 }619 // Update the remaining priority in the queue.620 if (updateExpirationTime > remainingExpirationTime) {621 remainingExpirationTime = updateExpirationTime;622 }623 } else {624 // This update does have sufficient priority.625 // Mark the event time of this update as relevant to this render pass.626 // TODO: This should ideally use the true event time of this update rather than627 // its priority which is a derived and not reverseable value.628 // TODO: We should skip this update if it was already committed but currently629 // we have no way of detecting the difference between a committed and suspended630 // update here.631 markRenderEventTime(updateExpirationTime);632 // Process this update.633 if (update.eagerReducer === reducer) {634 // If this update was processed eagerly, and its reducer matches the635 // current reducer, we can use the eagerly computed state.636 newState = ((update.eagerState: any): S);637 } else {638 const action = update.action;639 newState = reducer(newState, action);640 }641 }642 prevUpdate = update;643 update = update.next;644 } while (update !== null && update !== first);645 if (!didSkip) {646 newBaseUpdate = prevUpdate;647 newBaseState = newState;648 }649 // Mark that the fiber performed work, but only if the new state is650 // different from the current state.651 if (!is(newState, hook.memoizedState)) {652 markWorkInProgressReceivedUpdate();653 }654 hook.memoizedState = newState;655 hook.baseUpdate = newBaseUpdate;656 hook.baseState = newBaseState;657 queue.lastRenderedState = newState;658 }659 const dispatch: Dispatch<A> = (queue.dispatch: any);660 return [hook.memoizedState, dispatch];661}662function mountState<S>(663 initialState: (() => S) | S,664): [S, Dispatch<BasicStateAction<S>>] {665 const hook = mountWorkInProgressHook();666 if (typeof initialState === 'function') {667 initialState = initialState();668 }669 hook.memoizedState = hook.baseState = initialState;670 const queue = (hook.queue = {671 last: null,672 dispatch: null,673 lastRenderedReducer: basicStateReducer,674 lastRenderedState: (initialState: any),675 });676 const dispatch: Dispatch<677 BasicStateAction<S>,678 > = (queue.dispatch = (dispatchAction.bind(679 null,680 // Flow doesn't know this is non-null, but we do.681 ((currentlyRenderingFiber: any): Fiber),682 queue,683 ): any));684 return [hook.memoizedState, dispatch];685}686function updateState<S>(687 initialState: (() => S) | S,688): [S, Dispatch<BasicStateAction<S>>] {689 return updateReducer(basicStateReducer, (initialState: any));690}691function pushEffect(tag, create, destroy, deps) {692 const effect: Effect = {693 tag,694 create,695 destroy,696 deps,697 // Circular698 next: (null: any),699 };700 if (componentUpdateQueue === null) {701 componentUpdateQueue = createFunctionComponentUpdateQueue();702 componentUpdateQueue.lastEffect = effect.next = effect;703 } else {704 const lastEffect = componentUpdateQueue.lastEffect;705 if (lastEffect === null) {706 componentUpdateQueue.lastEffect = effect.next = effect;707 } else {708 const firstEffect = lastEffect.next;709 lastEffect.next = effect;710 effect.next = firstEffect;711 componentUpdateQueue.lastEffect = effect;712 }713 }714 return effect;715}716function mountRef<T>(initialValue: T): {current: T} {717 const hook = mountWorkInProgressHook();718 const ref = {current: initialValue};719 if (__DEV__) {720 Object.seal(ref);721 }722 hook.memoizedState = ref;723 return ref;724}725function updateRef<T>(initialValue: T): {current: T} {726 const hook = updateWorkInProgressHook();727 return hook.memoizedState;728}729function mountEffectImpl(fiberEffectTag, hookEffectTag, create, deps): void {730 const hook = mountWorkInProgressHook();731 const nextDeps = deps === undefined ? null : deps;732 sideEffectTag |= fiberEffectTag;733 hook.memoizedState = pushEffect(hookEffectTag, create, undefined, nextDeps);734}735function updateEffectImpl(fiberEffectTag, hookEffectTag, create, deps): void {736 const hook = updateWorkInProgressHook();737 const nextDeps = deps === undefined ? null : deps;738 let destroy = undefined;739 if (currentHook !== null) {740 const prevEffect = currentHook.memoizedState;741 destroy = prevEffect.destroy;742 if (nextDeps !== null) {743 const prevDeps = prevEffect.deps;744 if (areHookInputsEqual(nextDeps, prevDeps)) {745 pushEffect(NoHookEffect, create, destroy, nextDeps);746 return;747 }748 }749 }750 sideEffectTag |= fiberEffectTag;751 hook.memoizedState = pushEffect(hookEffectTag, create, destroy, nextDeps);752}753function mountEffect(754 create: () => (() => void) | void,755 deps: Array<mixed> | void | null,756): void {757 return mountEffectImpl(758 UpdateEffect | PassiveEffect,759 UnmountPassive | MountPassive,760 create,761 deps,762 );763}764function updateEffect(765 create: () => (() => void) | void,766 deps: Array<mixed> | void | null,767): void {768 return updateEffectImpl(769 UpdateEffect | PassiveEffect,770 UnmountPassive | MountPassive,771 create,772 deps,773 );774}775function mountLayoutEffect(776 create: () => (() => void) | void,777 deps: Array<mixed> | void | null,778): void {779 return mountEffectImpl(780 UpdateEffect,781 UnmountMutation | MountLayout,782 create,783 deps,784 );785}786function updateLayoutEffect(787 create: () => (() => void) | void,788 deps: Array<mixed> | void | null,789): void {790 return updateEffectImpl(791 UpdateEffect,792 UnmountMutation | MountLayout,793 create,794 deps,795 );796}797function imperativeHandleEffect<T>(798 create: () => T,799 ref: {current: T | null} | ((inst: T | null) => mixed) | null | void,800) {801 if (typeof ref === 'function') {802 const refCallback = ref;803 const inst = create();804 refCallback(inst);805 return () => {806 refCallback(null);807 };808 } else if (ref !== null && ref !== undefined) {809 const refObject = ref;810 if (__DEV__) {811 warning(812 refObject.hasOwnProperty('current'),813 'Expected useImperativeHandle() first argument to either be a ' +814 'ref callback or React.createRef() object. Instead received: %s.',815 'an object with keys {' + Object.keys(refObject).join(', ') + '}',816 );817 }818 const inst = create();819 refObject.current = inst;820 return () => {821 refObject.current = null;822 };823 }824}825function mountImperativeHandle<T>(826 ref: {current: T | null} | ((inst: T | null) => mixed) | null | void,827 create: () => T,828 deps: Array<mixed> | void | null,829): void {830 if (__DEV__) {831 warning(832 typeof create === 'function',833 'Expected useImperativeHandle() second argument to be a function ' +834 'that creates a handle. Instead received: %s.',835 create !== null ? typeof create : 'null',836 );837 }838 // TODO: If deps are provided, should we skip comparing the ref itself?839 const effectDeps =840 deps !== null && deps !== undefined ? deps.concat([ref]) : null;841 return mountEffectImpl(842 UpdateEffect,843 UnmountMutation | MountLayout,844 imperativeHandleEffect.bind(null, create, ref),845 effectDeps,846 );847}848function updateImperativeHandle<T>(849 ref: {current: T | null} | ((inst: T | null) => mixed) | null | void,850 create: () => T,851 deps: Array<mixed> | void | null,852): void {853 if (__DEV__) {854 warning(855 typeof create === 'function',856 'Expected useImperativeHandle() second argument to be a function ' +857 'that creates a handle. Instead received: %s.',858 create !== null ? typeof create : 'null',859 );860 }861 // TODO: If deps are provided, should we skip comparing the ref itself?862 const effectDeps =863 deps !== null && deps !== undefined ? deps.concat([ref]) : null;864 return updateEffectImpl(865 UpdateEffect,866 UnmountMutation | MountLayout,867 imperativeHandleEffect.bind(null, create, ref),868 effectDeps,869 );870}871function mountDebugValue<T>(value: T, formatterFn: ?(value: T) => mixed): void {872 // This hook is normally a no-op.873 // The react-debug-hooks package injects its own implementation874 // so that e.g. DevTools can display custom hook values.875}876const updateDebugValue = mountDebugValue;877function mountCallback<T>(callback: T, deps: Array<mixed> | void | null): T {878 const hook = mountWorkInProgressHook();879 const nextDeps = deps === undefined ? null : deps;880 hook.memoizedState = [callback, nextDeps];881 return callback;882}883function updateCallback<T>(callback: T, deps: Array<mixed> | void | null): T {884 const hook = updateWorkInProgressHook();885 const nextDeps = deps === undefined ? null : deps;886 const prevState = hook.memoizedState;887 if (prevState !== null) {888 if (nextDeps !== null) {889 const prevDeps: Array<mixed> | null = prevState[1];890 if (areHookInputsEqual(nextDeps, prevDeps)) {891 return prevState[0];892 }893 }894 }895 hook.memoizedState = [callback, nextDeps];896 return callback;897}898function mountMemo<T>(899 nextCreate: () => T,900 deps: Array<mixed> | void | null,901): T {902 const hook = mountWorkInProgressHook();903 const nextDeps = deps === undefined ? null : deps;904 const nextValue = nextCreate();905 hook.memoizedState = [nextValue, nextDeps];906 return nextValue;907}908function updateMemo<T>(909 nextCreate: () => T,910 deps: Array<mixed> | void | null,911): T {912 const hook = updateWorkInProgressHook();913 const nextDeps = deps === undefined ? null : deps;914 const prevState = hook.memoizedState;915 if (prevState !== null) {916 // Assume these are defined. If they're not, areHookInputsEqual will warn.917 if (nextDeps !== null) {918 const prevDeps: Array<mixed> | null = prevState[1];919 if (areHookInputsEqual(nextDeps, prevDeps)) {920 return prevState[0];921 }922 }923 }924 const nextValue = nextCreate();925 hook.memoizedState = [nextValue, nextDeps];926 return nextValue;927}928function dispatchAction<S, A>(929 fiber: Fiber,930 queue: UpdateQueue<S, A>,931 action: A,932) {933 invariant(934 numberOfReRenders < RE_RENDER_LIMIT,935 'Too many re-renders. React limits the number of renders to prevent ' +936 'an infinite loop.',937 );938 if (__DEV__) {939 warning(940 arguments.length <= 3,941 "State updates from the useState() and useReducer() Hooks don't support the " +942 'second callback argument. To execute a side effect after ' +943 'rendering, declare it in the component body with useEffect().',944 );945 }946 const alternate = fiber.alternate;947 if (948 fiber === currentlyRenderingFiber ||949 (alternate !== null && alternate === currentlyRenderingFiber)950 ) {951 // This is a render phase update. Stash it in a lazily-created map of952 // queue -> linked list of updates. After this render pass, we'll restart953 // and apply the stashed updates on top of the work-in-progress hook.954 didScheduleRenderPhaseUpdate = true;955 const update: Update<S, A> = {956 expirationTime: renderExpirationTime,957 action,958 eagerReducer: null,959 eagerState: null,960 next: null,961 };962 if (renderPhaseUpdates === null) {963 renderPhaseUpdates = new Map();964 }965 const firstRenderPhaseUpdate = renderPhaseUpdates.get(queue);966 if (firstRenderPhaseUpdate === undefined) {967 renderPhaseUpdates.set(queue, update);968 } else {969 // Append the update to the end of the list.970 let lastRenderPhaseUpdate = firstRenderPhaseUpdate;971 while (lastRenderPhaseUpdate.next !== null) {972 lastRenderPhaseUpdate = lastRenderPhaseUpdate.next;973 }974 lastRenderPhaseUpdate.next = update;975 }976 } else {977 flushPassiveEffects();978 const currentTime = requestCurrentTime();979 const expirationTime = computeExpirationForFiber(currentTime, fiber);980 const update: Update<S, A> = {981 expirationTime,982 action,983 eagerReducer: null,984 eagerState: null,985 next: null,986 };987 // Append the update to the end of the list.988 const last = queue.last;989 if (last === null) {990 // This is the first update. Create a circular list.991 update.next = update;992 } else {993 const first = last.next;994 if (first !== null) {995 // Still circular.996 update.next = first;997 }998 last.next = update;999 }1000 queue.last = update;1001 if (1002 fiber.expirationTime === NoWork &&1003 (alternate === null || alternate.expirationTime === NoWork)1004 ) {1005 // The queue is currently empty, which means we can eagerly compute the1006 // next state before entering the render phase. If the new state is the1007 // same as the current state, we may be able to bail out entirely.1008 const lastRenderedReducer = queue.lastRenderedReducer;1009 if (lastRenderedReducer !== null) {1010 let prevDispatcher;1011 if (__DEV__) {1012 prevDispatcher = ReactCurrentDispatcher.current;1013 ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnUpdateInDEV;1014 }1015 try {1016 const currentState: S = (queue.lastRenderedState: any);1017 const eagerState = lastRenderedReducer(currentState, action);1018 // Stash the eagerly computed state, and the reducer used to compute1019 // it, on the update object. If the reducer hasn't changed by the1020 // time we enter the render phase, then the eager state can be used1021 // without calling the reducer again.1022 update.eagerReducer = lastRenderedReducer;1023 update.eagerState = eagerState;1024 if (is(eagerState, currentState)) {1025 // Fast path. We can bail out without scheduling React to re-render.1026 // It's still possible that we'll need to rebase this update later,1027 // if the component re-renders for a different reason and by that1028 // time the reducer has changed.1029 return;1030 }1031 } catch (error) {1032 // Suppress the error. It will throw again in the render phase.1033 } finally {1034 if (__DEV__) {1035 ReactCurrentDispatcher.current = prevDispatcher;1036 }1037 }1038 }1039 }1040 if (__DEV__) {1041 // jest isn't a 'global', it's just exposed to tests via a wrapped function1042 // further, this isn't a test file, so flow doesn't recognize the symbol. So...1043 // $FlowExpectedError - because requirements don't give a damn about your type sigs.1044 if ('undefined' !== typeof jest) {1045 warnIfNotCurrentlyActingUpdatesInDev(fiber);1046 }1047 }1048 scheduleWork(fiber, expirationTime);1049 }1050}1051export const ContextOnlyDispatcher: Dispatcher = {1052 readContext,1053 useCallback: throwInvalidHookError,1054 useContext: throwInvalidHookError,1055 useEffect: throwInvalidHookError,1056 useImperativeHandle: throwInvalidHookError,1057 useLayoutEffect: throwInvalidHookError,1058 useMemo: throwInvalidHookError,1059 useReducer: throwInvalidHookError,1060 useRef: throwInvalidHookError,1061 useState: throwInvalidHookError,1062 useDebugValue: throwInvalidHookError,1063};1064const HooksDispatcherOnMount: Dispatcher = {1065 readContext,1066 useCallback: mountCallback,1067 useContext: readContext,1068 useEffect: mountEffect,1069 useImperativeHandle: mountImperativeHandle,1070 useLayoutEffect: mountLayoutEffect,1071 useMemo: mountMemo,1072 useReducer: mountReducer,1073 useRef: mountRef,1074 useState: mountState,1075 useDebugValue: mountDebugValue,1076};1077const HooksDispatcherOnUpdate: Dispatcher = {1078 readContext,1079 useCallback: updateCallback,1080 useContext: readContext,1081 useEffect: updateEffect,1082 useImperativeHandle: updateImperativeHandle,1083 useLayoutEffect: updateLayoutEffect,1084 useMemo: updateMemo,1085 useReducer: updateReducer,1086 useRef: updateRef,1087 useState: updateState,1088 useDebugValue: updateDebugValue,1089};1090let HooksDispatcherOnMountInDEV: Dispatcher | null = null;1091let HooksDispatcherOnMountWithHookTypesInDEV: Dispatcher | null = null;1092let HooksDispatcherOnUpdateInDEV: Dispatcher | null = null;1093let InvalidNestedHooksDispatcherOnMountInDEV: Dispatcher | null = null;1094let InvalidNestedHooksDispatcherOnUpdateInDEV: Dispatcher | null = null;1095if (__DEV__) {1096 const warnInvalidContextAccess = () => {1097 warning(1098 false,1099 'Context can only be read while React is rendering. ' +1100 'In classes, you can read it in the render method or getDerivedStateFromProps. ' +1101 'In function components, you can read it directly in the function body, but not ' +1102 'inside Hooks like useReducer() or useMemo().',1103 );1104 };1105 const warnInvalidHookAccess = () => {1106 warning(1107 false,1108 'Do not call Hooks inside useEffect(...), useMemo(...), or other built-in Hooks. ' +1109 'You can only call Hooks at the top level of your React function. ' +1110 'For more information, see ' +1111 'https://fb.me/rules-of-hooks',1112 );1113 };1114 HooksDispatcherOnMountInDEV = {1115 readContext<T>(1116 context: ReactContext<T>,1117 observedBits: void | number | boolean,1118 ): T {1119 return readContext(context, observedBits);1120 },1121 useCallback<T>(callback: T, deps: Array<mixed> | void | null): T {1122 currentHookNameInDev = 'useCallback';1123 mountHookTypesDev();1124 checkDepsAreArrayDev(deps);1125 return mountCallback(callback, deps);1126 },1127 useContext<T>(1128 context: ReactContext<T>,1129 observedBits: void | number | boolean,1130 ): T {1131 currentHookNameInDev = 'useContext';1132 mountHookTypesDev();1133 return readContext(context, observedBits);1134 },1135 useEffect(1136 create: () => (() => void) | void,1137 deps: Array<mixed> | void | null,1138 ): void {1139 currentHookNameInDev = 'useEffect';1140 mountHookTypesDev();1141 checkDepsAreArrayDev(deps);1142 return mountEffect(create, deps);1143 },1144 useImperativeHandle<T>(1145 ref: {current: T | null} | ((inst: T | null) => mixed) | null | void,1146 create: () => T,1147 deps: Array<mixed> | void | null,1148 ): void {1149 currentHookNameInDev = 'useImperativeHandle';1150 mountHookTypesDev();1151 checkDepsAreArrayDev(deps);1152 return mountImperativeHandle(ref, create, deps);1153 },1154 useLayoutEffect(1155 create: () => (() => void) | void,1156 deps: Array<mixed> | void | null,1157 ): void {1158 currentHookNameInDev = 'useLayoutEffect';1159 mountHookTypesDev();1160 checkDepsAreArrayDev(deps);1161 return mountLayoutEffect(create, deps);1162 },1163 useMemo<T>(create: () => T, deps: Array<mixed> | void | null): T {1164 currentHookNameInDev = 'useMemo';1165 mountHookTypesDev();1166 checkDepsAreArrayDev(deps);1167 const prevDispatcher = ReactCurrentDispatcher.current;1168 ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnMountInDEV;1169 try {1170 return mountMemo(create, deps);1171 } finally {1172 ReactCurrentDispatcher.current = prevDispatcher;1173 }1174 },1175 useReducer<S, I, A>(1176 reducer: (S, A) => S,1177 initialArg: I,1178 init?: I => S,1179 ): [S, Dispatch<A>] {1180 currentHookNameInDev = 'useReducer';1181 mountHookTypesDev();1182 const prevDispatcher = ReactCurrentDispatcher.current;1183 ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnMountInDEV;1184 try {1185 return mountReducer(reducer, initialArg, init);1186 } finally {1187 ReactCurrentDispatcher.current = prevDispatcher;1188 }1189 },1190 useRef<T>(initialValue: T): {current: T} {1191 currentHookNameInDev = 'useRef';1192 mountHookTypesDev();1193 return mountRef(initialValue);1194 },1195 useState<S>(1196 initialState: (() => S) | S,1197 ): [S, Dispatch<BasicStateAction<S>>] {1198 currentHookNameInDev = 'useState';1199 mountHookTypesDev();1200 const prevDispatcher = ReactCurrentDispatcher.current;1201 ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnMountInDEV;1202 try {1203 return mountState(initialState);1204 } finally {1205 ReactCurrentDispatcher.current = prevDispatcher;1206 }1207 },1208 useDebugValue<T>(value: T, formatterFn: ?(value: T) => mixed): void {1209 currentHookNameInDev = 'useDebugValue';1210 mountHookTypesDev();1211 return mountDebugValue(value, formatterFn);1212 },1213 };1214 HooksDispatcherOnMountWithHookTypesInDEV = {1215 readContext<T>(1216 context: ReactContext<T>,1217 observedBits: void | number | boolean,1218 ): T {1219 return readContext(context, observedBits);1220 },1221 useCallback<T>(callback: T, deps: Array<mixed> | void | null): T {1222 currentHookNameInDev = 'useCallback';1223 updateHookTypesDev();1224 return mountCallback(callback, deps);1225 },1226 useContext<T>(1227 context: ReactContext<T>,1228 observedBits: void | number | boolean,1229 ): T {1230 currentHookNameInDev = 'useContext';1231 updateHookTypesDev();1232 return readContext(context, observedBits);1233 },1234 useEffect(1235 create: () => (() => void) | void,1236 deps: Array<mixed> | void | null,1237 ): void {1238 currentHookNameInDev = 'useEffect';1239 updateHookTypesDev();1240 return mountEffect(create, deps);1241 },1242 useImperativeHandle<T>(1243 ref: {current: T | null} | ((inst: T | null) => mixed) | null | void,1244 create: () => T,1245 deps: Array<mixed> | void | null,1246 ): void {1247 currentHookNameInDev = 'useImperativeHandle';1248 updateHookTypesDev();1249 return mountImperativeHandle(ref, create, deps);1250 },1251 useLayoutEffect(1252 create: () => (() => void) | void,1253 deps: Array<mixed> | void | null,1254 ): void {1255 currentHookNameInDev = 'useLayoutEffect';1256 updateHookTypesDev();1257 return mountLayoutEffect(create, deps);1258 },1259 useMemo<T>(create: () => T, deps: Array<mixed> | void | null): T {1260 currentHookNameInDev = 'useMemo';1261 updateHookTypesDev();1262 const prevDispatcher = ReactCurrentDispatcher.current;1263 ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnMountInDEV;1264 try {1265 return mountMemo(create, deps);1266 } finally {1267 ReactCurrentDispatcher.current = prevDispatcher;1268 }1269 },1270 useReducer<S, I, A>(1271 reducer: (S, A) => S,1272 initialArg: I,1273 init?: I => S,1274 ): [S, Dispatch<A>] {1275 currentHookNameInDev = 'useReducer';1276 updateHookTypesDev();1277 const prevDispatcher = ReactCurrentDispatcher.current;1278 ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnMountInDEV;1279 try {1280 return mountReducer(reducer, initialArg, init);1281 } finally {1282 ReactCurrentDispatcher.current = prevDispatcher;1283 }1284 },1285 useRef<T>(initialValue: T): {current: T} {1286 currentHookNameInDev = 'useRef';1287 updateHookTypesDev();1288 return mountRef(initialValue);1289 },1290 useState<S>(1291 initialState: (() => S) | S,1292 ): [S, Dispatch<BasicStateAction<S>>] {1293 currentHookNameInDev = 'useState';1294 updateHookTypesDev();1295 const prevDispatcher = ReactCurrentDispatcher.current;1296 ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnMountInDEV;1297 try {1298 return mountState(initialState);1299 } finally {1300 ReactCurrentDispatcher.current = prevDispatcher;1301 }1302 },1303 useDebugValue<T>(value: T, formatterFn: ?(value: T) => mixed): void {1304 currentHookNameInDev = 'useDebugValue';1305 updateHookTypesDev();1306 return mountDebugValue(value, formatterFn);1307 },1308 };1309 HooksDispatcherOnUpdateInDEV = {1310 readContext<T>(1311 context: ReactContext<T>,1312 observedBits: void | number | boolean,1313 ): T {1314 return readContext(context, observedBits);1315 },1316 useCallback<T>(callback: T, deps: Array<mixed> | void | null): T {1317 currentHookNameInDev = 'useCallback';1318 updateHookTypesDev();1319 return updateCallback(callback, deps);1320 },1321 useContext<T>(1322 context: ReactContext<T>,1323 observedBits: void | number | boolean,1324 ): T {1325 currentHookNameInDev = 'useContext';1326 updateHookTypesDev();1327 return readContext(context, observedBits);1328 },1329 useEffect(1330 create: () => (() => void) | void,1331 deps: Array<mixed> | void | null,1332 ): void {1333 currentHookNameInDev = 'useEffect';1334 updateHookTypesDev();1335 return updateEffect(create, deps);1336 },1337 useImperativeHandle<T>(1338 ref: {current: T | null} | ((inst: T | null) => mixed) | null | void,1339 create: () => T,1340 deps: Array<mixed> | void | null,1341 ): void {1342 currentHookNameInDev = 'useImperativeHandle';1343 updateHookTypesDev();1344 return updateImperativeHandle(ref, create, deps);1345 },1346 useLayoutEffect(1347 create: () => (() => void) | void,1348 deps: Array<mixed> | void | null,1349 ): void {1350 currentHookNameInDev = 'useLayoutEffect';1351 updateHookTypesDev();1352 return updateLayoutEffect(create, deps);1353 },1354 useMemo<T>(create: () => T, deps: Array<mixed> | void | null): T {1355 currentHookNameInDev = 'useMemo';1356 updateHookTypesDev();1357 const prevDispatcher = ReactCurrentDispatcher.current;1358 ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnUpdateInDEV;1359 try {1360 return updateMemo(create, deps);1361 } finally {1362 ReactCurrentDispatcher.current = prevDispatcher;1363 }1364 },1365 useReducer<S, I, A>(1366 reducer: (S, A) => S,1367 initialArg: I,1368 init?: I => S,1369 ): [S, Dispatch<A>] {1370 currentHookNameInDev = 'useReducer';1371 updateHookTypesDev();1372 const prevDispatcher = ReactCurrentDispatcher.current;1373 ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnUpdateInDEV;1374 try {1375 return updateReducer(reducer, initialArg, init);1376 } finally {1377 ReactCurrentDispatcher.current = prevDispatcher;1378 }1379 },1380 useRef<T>(initialValue: T): {current: T} {1381 currentHookNameInDev = 'useRef';1382 updateHookTypesDev();1383 return updateRef(initialValue);1384 },1385 useState<S>(1386 initialState: (() => S) | S,1387 ): [S, Dispatch<BasicStateAction<S>>] {1388 currentHookNameInDev = 'useState';1389 updateHookTypesDev();1390 const prevDispatcher = ReactCurrentDispatcher.current;1391 ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnUpdateInDEV;1392 try {1393 return updateState(initialState);1394 } finally {1395 ReactCurrentDispatcher.current = prevDispatcher;1396 }1397 },1398 useDebugValue<T>(value: T, formatterFn: ?(value: T) => mixed): void {1399 currentHookNameInDev = 'useDebugValue';1400 updateHookTypesDev();1401 return updateDebugValue(value, formatterFn);1402 },1403 };1404 InvalidNestedHooksDispatcherOnMountInDEV = {1405 readContext<T>(1406 context: ReactContext<T>,1407 observedBits: void | number | boolean,1408 ): T {1409 warnInvalidContextAccess();1410 return readContext(context, observedBits);1411 },1412 useCallback<T>(callback: T, deps: Array<mixed> | void | null): T {1413 currentHookNameInDev = 'useCallback';1414 warnInvalidHookAccess();1415 mountHookTypesDev();1416 return mountCallback(callback, deps);1417 },1418 useContext<T>(1419 context: ReactContext<T>,1420 observedBits: void | number | boolean,1421 ): T {1422 currentHookNameInDev = 'useContext';1423 warnInvalidHookAccess();1424 mountHookTypesDev();1425 return readContext(context, observedBits);1426 },1427 useEffect(1428 create: () => (() => void) | void,1429 deps: Array<mixed> | void | null,1430 ): void {1431 currentHookNameInDev = 'useEffect';1432 warnInvalidHookAccess();1433 mountHookTypesDev();1434 return mountEffect(create, deps);1435 },1436 useImperativeHandle<T>(1437 ref: {current: T | null} | ((inst: T | null) => mixed) | null | void,1438 create: () => T,1439 deps: Array<mixed> | void | null,1440 ): void {1441 currentHookNameInDev = 'useImperativeHandle';1442 warnInvalidHookAccess();1443 mountHookTypesDev();1444 return mountImperativeHandle(ref, create, deps);1445 },1446 useLayoutEffect(1447 create: () => (() => void) | void,1448 deps: Array<mixed> | void | null,1449 ): void {1450 currentHookNameInDev = 'useLayoutEffect';1451 warnInvalidHookAccess();1452 mountHookTypesDev();1453 return mountLayoutEffect(create, deps);1454 },1455 useMemo<T>(create: () => T, deps: Array<mixed> | void | null): T {1456 currentHookNameInDev = 'useMemo';1457 warnInvalidHookAccess();1458 mountHookTypesDev();1459 const prevDispatcher = ReactCurrentDispatcher.current;1460 ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnMountInDEV;1461 try {1462 return mountMemo(create, deps);1463 } finally {1464 ReactCurrentDispatcher.current = prevDispatcher;1465 }1466 },1467 useReducer<S, I, A>(1468 reducer: (S, A) => S,1469 initialArg: I,1470 init?: I => S,1471 ): [S, Dispatch<A>] {1472 currentHookNameInDev = 'useReducer';1473 warnInvalidHookAccess();1474 mountHookTypesDev();1475 const prevDispatcher = ReactCurrentDispatcher.current;1476 ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnMountInDEV;1477 try {1478 return mountReducer(reducer, initialArg, init);1479 } finally {1480 ReactCurrentDispatcher.current = prevDispatcher;1481 }1482 },1483 useRef<T>(initialValue: T): {current: T} {1484 currentHookNameInDev = 'useRef';1485 warnInvalidHookAccess();1486 mountHookTypesDev();1487 return mountRef(initialValue);1488 },1489 useState<S>(1490 initialState: (() => S) | S,1491 ): [S, Dispatch<BasicStateAction<S>>] {1492 currentHookNameInDev = 'useState';1493 warnInvalidHookAccess();1494 mountHookTypesDev();1495 const prevDispatcher = ReactCurrentDispatcher.current;1496 ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnMountInDEV;1497 try {1498 return mountState(initialState);1499 } finally {1500 ReactCurrentDispatcher.current = prevDispatcher;1501 }1502 },1503 useDebugValue<T>(value: T, formatterFn: ?(value: T) => mixed): void {1504 currentHookNameInDev = 'useDebugValue';1505 warnInvalidHookAccess();1506 mountHookTypesDev();1507 return mountDebugValue(value, formatterFn);1508 },1509 };1510 InvalidNestedHooksDispatcherOnUpdateInDEV = {1511 readContext<T>(1512 context: ReactContext<T>,1513 observedBits: void | number | boolean,1514 ): T {1515 warnInvalidContextAccess();1516 return readContext(context, observedBits);1517 },1518 useCallback<T>(callback: T, deps: Array<mixed> | void | null): T {1519 currentHookNameInDev = 'useCallback';1520 warnInvalidHookAccess();1521 updateHookTypesDev();1522 return updateCallback(callback, deps);1523 },1524 useContext<T>(1525 context: ReactContext<T>,1526 observedBits: void | number | boolean,1527 ): T {1528 currentHookNameInDev = 'useContext';1529 warnInvalidHookAccess();1530 updateHookTypesDev();1531 return readContext(context, observedBits);1532 },1533 useEffect(1534 create: () => (() => void) | void,1535 deps: Array<mixed> | void | null,1536 ): void {1537 currentHookNameInDev = 'useEffect';1538 warnInvalidHookAccess();1539 updateHookTypesDev();1540 return updateEffect(create, deps);1541 },1542 useImperativeHandle<T>(1543 ref: {current: T | null} | ((inst: T | null) => mixed) | null | void,1544 create: () => T,1545 deps: Array<mixed> | void | null,1546 ): void {1547 currentHookNameInDev = 'useImperativeHandle';1548 warnInvalidHookAccess();1549 updateHookTypesDev();1550 return updateImperativeHandle(ref, create, deps);1551 },1552 useLayoutEffect(1553 create: () => (() => void) | void,1554 deps: Array<mixed> | void | null,1555 ): void {1556 currentHookNameInDev = 'useLayoutEffect';1557 warnInvalidHookAccess();1558 updateHookTypesDev();1559 return updateLayoutEffect(create, deps);1560 },1561 useMemo<T>(create: () => T, deps: Array<mixed> | void | null): T {1562 currentHookNameInDev = 'useMemo';1563 warnInvalidHookAccess();1564 updateHookTypesDev();1565 const prevDispatcher = ReactCurrentDispatcher.current;1566 ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnUpdateInDEV;1567 try {1568 return updateMemo(create, deps);1569 } finally {1570 ReactCurrentDispatcher.current = prevDispatcher;1571 }1572 },1573 useReducer<S, I, A>(1574 reducer: (S, A) => S,1575 initialArg: I,1576 init?: I => S,1577 ): [S, Dispatch<A>] {1578 currentHookNameInDev = 'useReducer';1579 warnInvalidHookAccess();1580 updateHookTypesDev();1581 const prevDispatcher = ReactCurrentDispatcher.current;1582 ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnUpdateInDEV;1583 try {1584 return updateReducer(reducer, initialArg, init);1585 } finally {1586 ReactCurrentDispatcher.current = prevDispatcher;1587 }1588 },1589 useRef<T>(initialValue: T): {current: T} {1590 currentHookNameInDev = 'useRef';1591 warnInvalidHookAccess();1592 updateHookTypesDev();1593 return updateRef(initialValue);1594 },1595 useState<S>(1596 initialState: (() => S) | S,1597 ): [S, Dispatch<BasicStateAction<S>>] {1598 currentHookNameInDev = 'useState';1599 warnInvalidHookAccess();1600 updateHookTypesDev();1601 const prevDispatcher = ReactCurrentDispatcher.current;1602 ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnUpdateInDEV;1603 try {1604 return updateState(initialState);1605 } finally {1606 ReactCurrentDispatcher.current = prevDispatcher;1607 }1608 },1609 useDebugValue<T>(value: T, formatterFn: ?(value: T) => mixed): void {1610 currentHookNameInDev = 'useDebugValue';1611 warnInvalidHookAccess();1612 updateHookTypesDev();1613 return updateDebugValue(value, formatterFn);1614 },1615 };...
learn-react-hook.js
Source:learn-react-hook.js
1// 以setState为ä¾åæreact-hookæºç ç¥è¯2// è¿éuseStateå
¶å®æ¯dispatcher对象éé¢çä¸ä¸ªæ¹æ³3export function useState < S > (initialState: (() => S) | S) {4 const dispatcher = resolveDispatcher();5 return dispatcher.useState(initialState);6}7// 继ç»è·è¸ªdispatcherå³resolveDispatcher()çè¿åå¼8function resolveDispatcher() {9 //主è¦è¿æ¯ä½¿ç¨çReactCurrentDispatcherè¿ä¸ªå¯¹è±¡çå¼10 const dispatcher = ReactCurrentDispatcher.current;11 //...12 return dispatcher;13}14// 继ç»è·ä¸ReactCurrentDispatcher15const ReactCurrentDispatcher = {16 /**17 * @internal18 * @type {ReactComponent}19 */20 // 追寻å°å
¶å®æå使ç¨çè¿æ¯reactèªèº«æä¾çDispatcher,æç»æåçè¿æ¯æ°çåè°å¨ä¸çFiberHooks21 // import type {Dispatcher} from 'react-reconciler/src/ReactFiberHooks';22 current: (null: null | Dispatcher),23};24// 继ç»è·è¿Dispatcher path: 'react-reconciler/src/ReactFiberHooks'25// è¿å
¥Dispatcher åç°Dispatcherççå½éé¢ä¸å¤§å ç¸å
³çhook,å
¨é¨é½å¨è¿éå®ä¹å¥½äºï¼æ¾å°useStateç声æ26export type Dispatcher = {27 readContext<T>(28 context: ReactContext<T>,29 observedBits: void | number | boolean,30 ): T,31 // useStateå®ä¹çæ ¼å¼ï¼ä¸ä¸ªè¿å
¥çæ³åSæ¯å½æ°æè
ä¸ä¸ªå¼ï¼åæ¶è¿åä¸ä¸ªS以åå¨ä½ç¨äºæ´æ°S32 useState<S>(initialState: (() => S) | S): [S, Dispatch<BasicStateAction<S>>],33 useReducer<S, I, A>(34 reducer: (S, A) => S,35 initialArg: I,36 init?: (I) => S,37 ): [S, Dispatch<A>],38 useContext<T>(39 context: ReactContext<T>,40 observedBits: void | number | boolean,41 ): T,42 useRef<T>(initialValue: T): {current: T},43 useEffect(44 create: () => (() => void) | void,45 deps: Array<mixed> | void | null,46 ): void,47 useLayoutEffect(48 create: () => (() => void) | void,49 deps: Array<mixed> | void | null,50 ): void,51 useCallback<T>(callback: T, deps: Array<mixed> | void | null): T,52 useMemo<T>(nextCreate: () => T, deps: Array<mixed> | void | null): T,53 useImperativeHandle<T>(54 ref: {current: T | null} | ((inst: T | null) => mixed) | null | void,55 create: () => T,56 deps: Array<mixed> | void | null,57 ): void,58 useDebugValue<T>(value: T, formatterFn: ?(value: T) => mixed): void,59};60// è·è¿Dispatcherçæ£çé»è¾å®ä½,åç°æåç§åæ ·çå®ä½ä½¿ç¨å°äºDispatcherçå®ä¹å¨æ¤éæ©hookæ载以åhookæ´æ°çç¶æå®ä½å»åæ61//Hooks æè½½å¨ç»ä»¶æ¶çæ
å½¢, å
¨é½æ¯mountç¶æ62const HooksDispatcherOnMount: Dispatcher = {63 readContext,64 useCallback: mountCallback,65 useContext: readContext,66 useEffect: mountEffect,67 useImperativeHandle: mountImperativeHandle,68 useLayoutEffect: mountLayoutEffect,69 useMemo: mountMemo,70 useReducer: mountReducer,71 useRef: mountRef,72 //useStateå¨mountç¶æçæ¶å对åºçmountStateè¿è¡è·è¸ª73 useState: mountState,74 useDebugValue: mountDebugValue,75};76// mountState ç¸å
³ç代ç 77function mountState<S>(78 initialState: (() => S) | S,79): [S, Dispatch<BasicStateAction<S>>] {80 // å®ä¹ä¸ä¸ªhookçä¸è¥¿ï¼è¿ä¸ªhookä¸ç¥éæ¯ä¸ªä»ä¹ä¸è¥¿ï¼å¥½åæ¯ä»workInProgressè¿ä¸ªFiberæ éé¢æ¿åºæ¥çä¸è¥¿81 const hook = mountWorkInProgressHook();82 if (typeof initialState === 'function') {83 // æ°æ§åå§ååå§ç¶æ84 initialState = initialState();85 }86 // å½åhookè®°ä½çç¶æmomoizedState = initialStateå³åå§åstateçå¼87 hook.memoizedState = hook.baseState = initialState;88 // å®ä¹ä¸ä¸ªhookçéå89 const queue = (hook.queue = {90 last: null, // ä¸æç½æ¯ä»ä¹ä¸è¥¿91 dispatch: null, // è¿ä¸ªæè§æç¹åç¶æ管ççå¨ä½è§¦åå¨92 lastRenderedReducer: basicStateReducer, //ä¸ç¥éä»ä¹ä¸è¥¿ï¼æ ¹æ®å½åï¼å¯ä»¥è®¤ä¸ºæ¯ä¸ä¸æ¬¡æ¸²æçrenducer93 lastRenderedState: (initialState: any), // è¿ä¸ªåºè¯¥æ¯ä¸ä¸æ¬¡æ¸²æçstateå¦94 });95 const dispatch: Dispatch<96 BasicStateAction<S>,97 > = (queue.dispatch = (dispatchAction.bind(98 null,99 // Flow doesn't know this is non-null, but we do.100 ((currentlyRenderingFiber: any): Fiber),101 queue,102 ): any)); // è¿éhook.queue.dispatchå
¶å®å°±æ¯reactéé¢å
ç½®çä¸ä¸ªdispatchActionçå½æ°ï¼å
·ä½éé¢ä¼°è®¡æ¯å¹²åçä¸å¤ªæ¸
æ¥ï¼ç¨ååæ103 return [hook.memoizedState, dispatch];104}105/**106 * è¿éåæ以ä¸çmountStateåå æ¥è¿è¡107 * 1ãmountWorkInProgressHookè¿ä¸ªå½æ°éé¢è¿åçæ¯ä»ä¹ä¸è¥¿ï¼éé¢æä»ä¹ä¸è¥¿ï¼ä¸ºä»ä¹å½å为hook?108 * 2ãdispatchActionå½æ°109 * 3ãæ¤æ¥å¯ä¸ç¨è¿ä¹è¯¦ç»è¿è¡åæï¼basicStateReduceræ¯ä»ä¹ï¼å®æä»ä¹ç¨ï¼æä¹ç¨ï¼ä»¥åcurrentlyRenderingFiberæ¯ä¸ªä»ä¹ä¸è¥¿110 */111 // 1ãmountWorkInProgressHookæ¯ä¸ªä»ä¹ä¸è¥¿112 function mountWorkInProgressHook(): Hook {113 // å
¶å®å°±æ¯è¿åä¸ä¸ªhookï¼å°±æ¯ä¸ä¸ªç®åç对象114 const hook: Hook = {115 memoizedState: null,116 baseState: null,117 queue: null,118 baseUpdate: null,119 next: null,120 };121 // è¿éå
¶å®å°±æ¯æ建ä¸ä¸ªç±»ä¼¼é¾è¡¨çä¸è¥¿ï¼122 // HookA -> HookB -> HookC -> HookD ?123 // æè§å°±æ¯è¿ä¸ªä¸è¥¿äºæåæå½åé¾è¡¨èç¹è¿å124 if (workInProgressHook === null) {125 // This is the first hook in the list126 // è¿ä¸ªfirstWorkInprogressHookä¼¼ä¹æ¯å
¨å±åé127 firstWorkInProgressHook = workInProgressHook = hook;128 } else {129 // Append to the end of the list130 workInProgressHook = workInProgressHook.next = hook;131 }132 return workInProgressHook;133}134// 2ãæç½äºhookæ¯ä¸ªä»ä¹ä¸è¥¿ï¼ç°å¨ç¬¬äºæ¥ï¼dispatcherActionæ¯ä¸ªä»ä¹ä¸è¥¿?135// è¿ä¸ªä¸è¥¿æ¯è¾é¾åçèµ·æ¥å°±æºå¤æçï¼ä½æ¯ç°å¨å±ä»¬å
ä¸å»å¨å®ï¼å 为å±ä»¬åªæ¯è¿è¡çä¸ä¸ªæè½½å¨ä½ï¼æ²¡æä»»ä½å¨ä½è¡ä¸ºï¼æ æ³è§¦å该å½æ°æ§è¡136function dispatchAction<S, A>(137 fiber: Fiber, // currentlyRenderingFiber138 queue: UpdateQueue<S, A>, // mounté¶æ®µqueue {last: null, lastRenderedReducer: basicStateReducer, lastRenderedState: (initialState: any)}139 action: A, // mounté¶æ®µ action 为undefined140) {141 invariant(142 numberOfReRenders < RE_RENDER_LIMIT,143 'Too many re-renders. React limits the number of renders to prevent ' +144 'an infinite loop.',145 );146 if (__DEV__) {147 warning(148 arguments.length <= 3,149 "State updates from the useState() and useReducer() Hooks don't support the " +150 'second callback argument. To execute a side effect after ' +151 'rendering, declare it in the component body with useEffect().',152 );153 }154 const alternate = fiber.alternate;155 if (156 fiber === currentlyRenderingFiber ||157 (alternate !== null && alternate === currentlyRenderingFiber)158 ) {159 // This is a render phase update. Stash it in a lazily-created map of160 // queue -> linked list of updates. After this render pass, we'll restart161 // and apply the stashed updates on top of the work-in-progress hook.162 didScheduleRenderPhaseUpdate = true;163 const update: Update<S, A> = {164 expirationTime: renderExpirationTime,165 action,166 eagerReducer: null,167 eagerState: null,168 next: null,169 };170 if (renderPhaseUpdates === null) {171 renderPhaseUpdates = new Map();172 }173 const firstRenderPhaseUpdate = renderPhaseUpdates.get(queue);174 if (firstRenderPhaseUpdate === undefined) {175 renderPhaseUpdates.set(queue, update);176 } else {177 // Append the update to the end of the list.178 let lastRenderPhaseUpdate = firstRenderPhaseUpdate;179 while (lastRenderPhaseUpdate.next !== null) {180 lastRenderPhaseUpdate = lastRenderPhaseUpdate.next;181 }182 lastRenderPhaseUpdate.next = update;183 }184 } else {185 flushPassiveEffects();186 const currentTime = requestCurrentTime();187 const expirationTime = computeExpirationForFiber(currentTime, fiber);188 const update: Update<S, A> = {189 expirationTime,190 action,191 eagerReducer: null,192 eagerState: null,193 next: null,194 };195 // Append the update to the end of the list.196 const last = queue.last;197 if (last === null) {198 // This is the first update. Create a circular list.199 update.next = update;200 } else {201 const first = last.next;202 if (first !== null) {203 // Still circular.204 update.next = first;205 }206 last.next = update;207 }208 queue.last = update;209 if (210 fiber.expirationTime === NoWork &&211 (alternate === null || alternate.expirationTime === NoWork)212 ) {213 // The queue is currently empty, which means we can eagerly compute the214 // next state before entering the render phase. If the new state is the215 // same as the current state, we may be able to bail out entirely.216 const lastRenderedReducer = queue.lastRenderedReducer;217 if (lastRenderedReducer !== null) {218 let prevDispatcher;219 if (__DEV__) {220 prevDispatcher = ReactCurrentDispatcher.current;221 ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnUpdateInDEV;222 }223 try {224 const currentState: S = (queue.lastRenderedState: any);225 const eagerState = lastRenderedReducer(currentState, action);226 // Stash the eagerly computed state, and the reducer used to compute227 // it, on the update object. If the reducer hasn't changed by the228 // time we enter the render phase, then the eager state can be used229 // without calling the reducer again.230 update.eagerReducer = lastRenderedReducer;231 update.eagerState = eagerState;232 if (is(eagerState, currentState)) {233 // Fast path. We can bail out without scheduling React to re-render.234 // It's still possible that we'll need to rebase this update later,235 // if the component re-renders for a different reason and by that236 // time the reducer has changed.237 return;238 }239 } catch (error) {240 // Suppress the error. It will throw again in the render phase.241 } finally {242 if (__DEV__) {243 ReactCurrentDispatcher.current = prevDispatcher;244 }245 }246 }247 }248 if (__DEV__) {249 // jest isn't a 'global', it's just exposed to tests via a wrapped function250 // further, this isn't a test file, so flow doesn't recognize the symbol. So...251 // $FlowExpectedError - because requirements don't give a damn about your type sigs.252 if ('undefined' !== typeof jest) {253 warnIfNotCurrentlyActingUpdatesInDev(fiber);254 }255 }256 scheduleWork(fiber, expirationTime);257 }258}259// 第ä¸æ¥ï¼ææ 260// ç°å¨ç¸å½äºåå§å好äºsetStateçhookå°±å¦åæ§è¡äºä¸æ¬¡ä¸é¢ç代ç 261const [name, setName] = useState('initialName');...
ReactFiberScheduler.js
Source:ReactFiberScheduler.js
1/**2 * Copyright (c) Facebook, Inc. and its affiliates.3 *4 * This source code is licensed under the MIT license found in the5 * LICENSE file in the root directory of this source tree.6 *7 * @flow8 */9import {enableNewScheduler} from 'shared/ReactFeatureFlags';10import {11 requestCurrentTime as requestCurrentTime_old,12 computeExpirationForFiber as computeExpirationForFiber_old,13 captureCommitPhaseError as captureCommitPhaseError_old,14 onUncaughtError as onUncaughtError_old,15 renderDidSuspend as renderDidSuspend_old,16 renderDidError as renderDidError_old,17 pingSuspendedRoot as pingSuspendedRoot_old,18 retryTimedOutBoundary as retryTimedOutBoundary_old,19 resolveRetryThenable as resolveRetryThenable_old,20 markLegacyErrorBoundaryAsFailed as markLegacyErrorBoundaryAsFailed_old,21 isAlreadyFailedLegacyErrorBoundary as isAlreadyFailedLegacyErrorBoundary_old,22 scheduleWork as scheduleWork_old,23 flushRoot as flushRoot_old,24 batchedUpdates as batchedUpdates_old,25 unbatchedUpdates as unbatchedUpdates_old,26 flushSync as flushSync_old,27 flushControlled as flushControlled_old,28 deferredUpdates as deferredUpdates_old,29 syncUpdates as syncUpdates_old,30 interactiveUpdates as interactiveUpdates_old,31 flushInteractiveUpdates as flushInteractiveUpdates_old,32 computeUniqueAsyncExpiration as computeUniqueAsyncExpiration_old,33 flushPassiveEffects as flushPassiveEffects_old,34 warnIfNotCurrentlyActingUpdatesInDev as warnIfNotCurrentlyActingUpdatesInDev_old,35 inferStartTimeFromExpirationTime as inferStartTimeFromExpirationTime_old,36} from './ReactFiberScheduler.old';37import {38 requestCurrentTime as requestCurrentTime_new,39 computeExpirationForFiber as computeExpirationForFiber_new,40 captureCommitPhaseError as captureCommitPhaseError_new,41 onUncaughtError as onUncaughtError_new,42 renderDidSuspend as renderDidSuspend_new,43 renderDidError as renderDidError_new,44 pingSuspendedRoot as pingSuspendedRoot_new,45 retryTimedOutBoundary as retryTimedOutBoundary_new,46 resolveRetryThenable as resolveRetryThenable_new,47 markLegacyErrorBoundaryAsFailed as markLegacyErrorBoundaryAsFailed_new,48 isAlreadyFailedLegacyErrorBoundary as isAlreadyFailedLegacyErrorBoundary_new,49 scheduleWork as scheduleWork_new,50 flushRoot as flushRoot_new,51 batchedUpdates as batchedUpdates_new,52 unbatchedUpdates as unbatchedUpdates_new,53 flushSync as flushSync_new,54 flushControlled as flushControlled_new,55 deferredUpdates as deferredUpdates_new,56 syncUpdates as syncUpdates_new,57 interactiveUpdates as interactiveUpdates_new,58 flushInteractiveUpdates as flushInteractiveUpdates_new,59 computeUniqueAsyncExpiration as computeUniqueAsyncExpiration_new,60 flushPassiveEffects as flushPassiveEffects_new,61 warnIfNotCurrentlyActingUpdatesInDev as warnIfNotCurrentlyActingUpdatesInDev_new,62 inferStartTimeFromExpirationTime as inferStartTimeFromExpirationTime_new,63} from './ReactFiberScheduler.new';64// enableNewScheduler é½ä¸º falseï¼æ以æ们åªç old ç代ç 65export const requestCurrentTime = enableNewScheduler66 ? requestCurrentTime_new67 : requestCurrentTime_old;68export const computeExpirationForFiber = enableNewScheduler69 ? computeExpirationForFiber_new70 : computeExpirationForFiber_old;71export const captureCommitPhaseError = enableNewScheduler72 ? captureCommitPhaseError_new73 : captureCommitPhaseError_old;74export const onUncaughtError = enableNewScheduler75 ? onUncaughtError_new76 : onUncaughtError_old;77export const renderDidSuspend = enableNewScheduler78 ? renderDidSuspend_new79 : renderDidSuspend_old;80export const renderDidError = enableNewScheduler81 ? renderDidError_new82 : renderDidError_old;83export const pingSuspendedRoot = enableNewScheduler84 ? pingSuspendedRoot_new85 : pingSuspendedRoot_old;86export const retryTimedOutBoundary = enableNewScheduler87 ? retryTimedOutBoundary_new88 : retryTimedOutBoundary_old;89export const resolveRetryThenable = enableNewScheduler90 ? resolveRetryThenable_new91 : resolveRetryThenable_old;92export const markLegacyErrorBoundaryAsFailed = enableNewScheduler93 ? markLegacyErrorBoundaryAsFailed_new94 : markLegacyErrorBoundaryAsFailed_old;95export const isAlreadyFailedLegacyErrorBoundary = enableNewScheduler96 ? isAlreadyFailedLegacyErrorBoundary_new97 : isAlreadyFailedLegacyErrorBoundary_old;98export const scheduleWork = enableNewScheduler99 ? scheduleWork_new100 : scheduleWork_old;101export const flushRoot = enableNewScheduler ? flushRoot_new : flushRoot_old;102export const batchedUpdates = enableNewScheduler103 ? batchedUpdates_new104 : batchedUpdates_old;105export const unbatchedUpdates = enableNewScheduler106 ? unbatchedUpdates_new107 : unbatchedUpdates_old;108export const flushSync = enableNewScheduler ? flushSync_new : flushSync_old;109export const flushControlled = enableNewScheduler110 ? flushControlled_new111 : flushControlled_old;112export const deferredUpdates = enableNewScheduler113 ? deferredUpdates_new114 : deferredUpdates_old;115export const syncUpdates = enableNewScheduler116 ? syncUpdates_new117 : syncUpdates_old;118export const interactiveUpdates = enableNewScheduler119 ? interactiveUpdates_new120 : interactiveUpdates_old;121export const flushInteractiveUpdates = enableNewScheduler122 ? flushInteractiveUpdates_new123 : flushInteractiveUpdates_old;124export const computeUniqueAsyncExpiration = enableNewScheduler125 ? computeUniqueAsyncExpiration_new126 : computeUniqueAsyncExpiration_old;127export const flushPassiveEffects = enableNewScheduler128 ? flushPassiveEffects_new129 : flushPassiveEffects_old;130export const warnIfNotCurrentlyActingUpdatesInDev = enableNewScheduler131 ? warnIfNotCurrentlyActingUpdatesInDev_new132 : warnIfNotCurrentlyActingUpdatesInDev_old;133export const inferStartTimeFromExpirationTime = enableNewScheduler134 ? inferStartTimeFromExpirationTime_new135 : inferStartTimeFromExpirationTime_old;136export type Thenable = {137 then(resolve: () => mixed, reject?: () => mixed): void | Thenable,...
insp.js
Source:insp.js
1import React from "react";2import { render } from "@testing-library/react";3import Inspiration from "./Inspiration";4import { act } from "react-dom/test-utils";5import { MemoryRouter } from "react-router";6import { getPictures } from "./Inspiration";7jest.mock("./Inspiration");8const testEvents = [9 {10 id: 1,11 title: "Anniversary",12 description: "Anniversary",13 eventDate: "2021-05-19",14 eventTime: "13:00",15 city: "Minsk",16 state: "CA",17 country: "Belarus",18 imgUrl:19 "https://images.unsplash.com/photo-1532117182044-031e7cd916ee?ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&ixlib=rb-1.2.1&auto=format&fit=crop&w=800&q=80",20 hostUsername: "testuser"21 },22 {23 id: 2,24 title: "Wedding",25 description: "Wedding",26 eventDate: "2021-05-19",27 eventTime: "13:00",28 city: "Minsk",29 state: "CA",30 country: "Belarus",31 imgUrl:32 "https://images.unsplash.com/photo-1532117182044-031e7cd916ee?ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&ixlib=rb-1.2.1&auto=format&fit=crop&w=800&q=80",33 hostUsername: "testuser"34 }35];36const currentUser = { username: "testuser", isAdmin: false };37it("renders without crashing", async () => {38 act(() => {39 render(40 <MemoryRouter>41 <Inspiration events={testEvents} currentUser={currentUser} />42 </MemoryRouter>43 );44 });45 expect(screen.getByText("Loading...")).toBeInTheDocument();46 expect(getPictures).toHaveBeenCalledTimes(1);47});48// 1 fail - Inspiration(...): Nothing was returned from render. This usually means a return statement is missing. Or, to render nothing, return null.49it("shows text on the page", async () => {50 await act(async () => {51 const { getByText } = render(52 <MemoryRouter>53 <Inspiration events={testEvents} currentUser={currentUser} />54 </MemoryRouter>55 );56 await waitFor(() => expect(getByText("add")).toBeInTheDocument());57 });58});59// 2 passed - Warning: An update to Inspiration inside a test was not wrapped in act(...).60// When testing, code that causes React state updates should be wrapped into act(...):61// act(() => {62// /* fire events that update state */63// });64// /* assert on the output */65// This ensures that you're testing the behavior the user would see in the browser. Learn more at https://reactjs.org/link/wrap-tests-with-act66// at Inspiration (/Users/jayres/Desktop/BoogieBot/frontend/src/Inspiration.js:37:3)67// at Router (/Users/jayres/Desktop/BoogieBot/frontend/node_modules/react-router/cjs/react-router.js:99:30)68// at MemoryRouter (/Users/jayres/Desktop/BoogieBot/frontend/node_modules/react-router/cjs/react-router.js:187:35)69// 60 | };70// 61 |71// > 62 | async function handleSubmit (e) {72// | ^73// 63 | e.preventDefault();74// 64 | setFormErrors([]);75// 65 |76// at printWarning (node_modules/react-dom/cjs/react-dom.development.js:67:30)77// at error (node_modules/react-dom/cjs/react-dom.development.js:43:5)78// at warnIfNotCurrentlyActingUpdatesInDEV (node_modules/react-dom/cjs/react-dom.development.js:24064:9)79// at dispatchAction (node_modules/react-dom/cjs/react-dom.development.js:16135:9)...
Using AI Code Generation
1const playwright = require('playwright');2(async () => {3 const browser = await playwright['chromium'].launch();4 const context = await browser.newContext();5 const page = await context.newPage();6 await page.click('text=Sign in');7 await page.fill('input[type="email"]', '
Using AI Code Generation
1const playwright = require('playwright');2(async () => {3 const browser = await playwright.chromium.launch();4 const context = await browser.newContext();5 const page = await context.newPage();6 await page.screenshot({ path: 'example.png' });7 await browser.close();8})();9const { devices } = require('playwright');10module.exports = {11 use: {12 viewport: { width: 1280, height: 720 },13 },14};15import { devices } from 'playwright';16export default {17 use: {18 viewport: { width: 1280, height: 720 },19 },20};21const { devices } = require('playwright');22module.exports = {23 use: {24 viewport: { width: 1280, height: 720 },25 },26};27import { devices } from 'playwright';28export default {29 use: {30 viewport: { width: 1280, height:
Using AI Code Generation
1const playwright = require('playwright');2const { warnIfNotCurrentlyActingUpdatesInDEV } = require('playwright/lib/server/supplements/recorder/recorderSupplement');3(async () => {4 const browser = await playwright.chromium.launch();5 const page = await browser.newPage();6 await page.click('text="I agree"');7 await page.click('text="Sign in"');8 await page.click('input[aria-label="Email or phone"]');9 await page.fill('input[aria-label="Email or phone"]', '
Using AI Code Generation
1const { warnIfNotCurrentlyActingUpdatesInDEV } = require('@playwright/test/lib/server/frames');2const { warnIfNotCurrentlyActingUpdatesInDEV } = require('@playwright/test/lib/server/frames');3warnIfNotCurrentlyActingUpdatesInDEV();4const { warnIfNotCurrentlyActingUpdatesInDEV } = require('@playwright/test/lib/server/frames');5warnIfNotCurrentlyActingUpdatesInDEV();6const { warnIfNotCurrentlyActingUpdatesInDEV } = require('@playwright/test/lib/server/frames');7warnIfNotCurrentlyActingUpdatesInDEV();8const { warnIfNotCurrentlyActingUpdatesInDEV } = require('@playwright/test/lib/server/frames');9warnIfNotCurrentlyActingUpdatesInDEV();10const { warnIfNotCurrentlyActingUpdatesInDEV } = require('@playwright/test/lib/server/frames');11warnIfNotCurrentlyActingUpdatesInDEV();12const { warnIfNotCurrentlyActingUpdatesInDEV } = require('@playwright/test/lib/server/frames');13warnIfNotCurrentlyActingUpdatesInDEV();14const { warnIfNotCurrentlyActingUpdatesInDEV } = require('@playwright/test/lib/server/frames');15warnIfNotCurrentlyActingUpdatesInDEV();16const { warnIfNotCurrentlyActingUpdatesInDEV } = require('@playwright/test/lib/server/frames');17warnIfNotCurrentlyActingUpdatesInDEV();18const { warnIfNotCurrentlyActingUpdatesInDEV } = require('@playwright/test/lib/server/frames');19warnIfNotCurrentlyActingUpdatesInDEV();
Using AI Code Generation
1const { warnIfNotCurrentlyActingUpdatesInDEV } = require('playwright/lib/server/browserContext');2const { chromium } = require('playwright');3const browser = await chromium.launch();4const context = await browser.newContext();5const page = await context.newPage();6await page.click('text=Google apps');7await page.click('text=Translate');8await page.fill('input#source', 'Hello World');9await page.click('text=English');10await page.click('text=Spanish');11await page.click('text=Listen');12await page.click('text=Play');13await page.click('text=Pause');14await page.click('text=Stop');15warnIfNotCurrentlyActingUpdatesInDEV(page, 'click', 'text=Pause');16await page.click('text=Pause');17await page.close();18await context.close();19await browser.close();20const { warnIfNotCurrentlyActingUpdatesInDEV } = require('playwright/lib/server/browserContext');21const { chromium } = require('playwright');22const browser = await chromium.launch();23const context = await browser.newContext();24const page = await context.newPage();25await page.click('text=Google apps');26await page.click('text=Translate');27await page.fill('input#source', 'Hello World');28await page.click('text=English');29await page.click('text=Spanish');30await page.click('text=Listen');31await page.click('text=Play');32await page.click('text=Pause');33await page.click('text=Stop');34warnIfNotCurrentlyActingUpdatesInDEV(page, 'click', 'text=Stop');35await page.click('text=Stop');
Using AI Code Generation
1const { warnIfNotCurrentlyActingUpdatesInDEV } = require('@playwright/test/lib/server/frames');2const { Frame } = require('@playwright/test/lib/server/frames');3const frame = new Frame(null, null, null, null, null, null, null, null, null, null, null, null, null, null);4warnIfNotCurrentlyActingUpdatesInDEV(frame, 'test');5const { warnIfNotCurrentlyActingUpdatesInDEV } = require('playwright');6const { Frame } = require('playwright');7const frame = new Frame(null, null, null, null, null, null, null, null, null, null, null, null, null, null);8warnIfNotCurrentlyActingUpdatesInDEV(frame, 'test');
Using AI Code Generation
1const { warnIfNotCurrentlyActingUpdatesInDEV } = require('@playwright/test/lib/internal/utils');2const { warnIfNotCurrentlyActingUpdatesInDEV } = require('@playwright/test/lib/internal/utils');3const { test, expect } = require('@playwright/test');4test('should pass', async ({ page }) => {5expect(await page.innerText('text=Get started')).toBe('Get started');6});
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.
Get 100 minutes of automation test minutes FREE!!