How to use warnIfNotCurrentlyActingUpdatesInDEV method in Playwright Internal

Best JavaScript code snippet using playwright-internal

ReactFiberWorkLoop.js

Source:ReactFiberWorkLoop.js Github

copy

Full Screen

...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' +...

Full Screen

Full Screen

ReactFiberWorkLoop.old.js

Source:ReactFiberWorkLoop.old.js Github

copy

Full Screen

...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 }...

Full Screen

Full Screen

ReactFiberScheduler.new.js

Source:ReactFiberScheduler.new.js Github

copy

Full Screen

...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' +...

Full Screen

Full Screen

ReactFiberHooks.js

Source:ReactFiberHooks.js Github

copy

Full Screen

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 };...

Full Screen

Full Screen

learn-react-hook.js

Source:learn-react-hook.js Github

copy

Full Screen

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');...

Full Screen

Full Screen

ReactFiberScheduler.js

Source:ReactFiberScheduler.js Github

copy

Full Screen

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,...

Full Screen

Full Screen

insp.js

Source:insp.js Github

copy

Full Screen

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)...

Full Screen

Full Screen

Using AI Code Generation

copy

Full Screen

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"]', '

Full Screen

Using AI Code Generation

copy

Full Screen

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:

Full Screen

Using AI Code Generation

copy

Full Screen

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"]', '

Full Screen

Using AI Code Generation

copy

Full Screen

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();

Full Screen

Using AI Code Generation

copy

Full Screen

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');

Full Screen

Using AI Code Generation

copy

Full Screen

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');

Full Screen

Using AI Code Generation

copy

Full Screen

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});

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