// The following should have already been reset // currentHook = null; // workInProgressHook = null;
// didScheduleRenderPhaseUpdate = false;
// TODO Warn if no hooks are used at all during mount, then some are used during update. // Currently we will identify the update render as a mount because memoizedState === null. // This is tricky because it's valid for certain types of components (e.g. React.lazy)
// Using memoizedState to differentiate between mount/update only works if at least one stateful hook is used. // Non-stateful hooks (e.g. context) don't get added to memoizedState, // so memoizedState would be null during updates and mounts. ReactCurrentDispatcher.current = current === null || current.memoizedState === null ? HooksDispatcherOnMount : HooksDispatcherOnUpdate;
let children = Component(props, secondArg);
// Check if there was a render phase update if (didScheduleRenderPhaseUpdateDuringThisPass) { // Keep rendering in a loop for as long as render phase updates continue to // be scheduled. Use a counter to prevent infinite loops. let numberOfReRenders: number = 0; do { didScheduleRenderPhaseUpdateDuringThisPass = false; invariant( numberOfReRenders < RE_RENDER_LIMIT, 'Too many re-renders. React limits the number of renders to prevent ' + 'an infinite loop.', );
numberOfReRenders += 1; // Start over from the beginning of the list currentHook = null; workInProgressHook = null;
children = Component(props, secondArg); } while (didScheduleRenderPhaseUpdateDuringThisPass); } // We can assume the previous dispatcher is always this one, since we set it // at the beginning of the render phase and there's no re-entrancy. ReactCurrentDispatcher.current = ContextOnlyDispatcher;
// This check uses currentHook so that it works the same in DEV and prod bundles. // hookTypesDev could catch more cases (e.g. context) but only in DEV bundles. const didRenderTooFewHooks = currentHook !== null && currentHook.next !== null;
try { const currentState: S = (queue.lastRenderedState: any); const eagerState = lastRenderedReducer(currentState, action); // Stash the eagerly computed state, and the reducer used to compute // it, on the update object. If the reducer hasn't changed by the // time we enter the render phase, then the eager state can be used // without calling the reducer again. update.eagerReducer = lastRenderedReducer; update.eagerState = eagerState; if (is(eagerState, currentState)) { // Fast path. We can bail out without scheduling React to re-render. // It's still possible that we'll need to rebase this update later, // if the component re-renders for a different reason and by that // time the reducer has changed. return; } } catch (error) { // Suppress the error. It will throw again in the render phase. }
const instance = workInProgress.stateNode; // 注意这里!!! // 这里出现了 should update !!! let shouldUpdate; if (instance === null) { if (current !== null) { // A class component without an instance only mounts if it suspended // inside a non-concurrent tree, in an inconsistent state. We want to // treat it like a new mount, even though an empty version of it already // committed. Disconnect the alternate pointers. current.alternate = null; workInProgress.alternate = null; // Since this is conceptually a new fiber, schedule a Placement effect workInProgress.flags |= Placement; } // In the initial pass we might need to construct the instance. constructClassInstance(workInProgress, Component, nextProps); mountClassInstance(workInProgress, Component, nextProps, renderLanes); shouldUpdate = true; } else if (current === null) { // In a resume, we'll already have an instance we can reuse. shouldUpdate = resumeMountClassInstance( workInProgress, Component, nextProps, renderLanes ); } else { shouldUpdate = updateClassInstance( current, workInProgress, Component, nextProps, renderLanes ); } const nextUnitOfWork = finishClassComponent( current, workInProgress, Component, shouldUpdate, hasContext, renderLanes ); return nextUnitOfWork; }
后面的 finishClassComponent 我也不贴了,大家可以去看,反正会有一系列的判断,然后再进入 children 的 reconcile
啥意思?
先不管 workInProgress 的静态化,异步过程,调度过程
请问 ——
shouldUpdate 的概念,在 React function component 中,有没有意义?