@@ -23,14 +23,18 @@ import {isPrimaryRenderer} from './ReactFiberHostConfig';
2323import { createCursor , push , pop } from './ReactFiberStack' ;
2424import maxSigned31BitInt from './maxSigned31BitInt' ;
2525import { NoWork } from './ReactFiberExpirationTime' ;
26- import { ContextProvider } from 'shared/ReactTypeOfWork' ;
26+ import { ContextProvider , ClassComponent } from 'shared/ReactTypeOfWork' ;
2727
2828import invariant from 'shared/invariant' ;
2929import warning from 'shared/warning' ;
30+ import {
31+ createUpdate ,
32+ enqueueUpdate ,
33+ ForceUpdate ,
34+ } from 'react-reconciler/src/ReactUpdateQueue' ;
3035
3136import MAX_SIGNED_31_BIT_INT from './maxSigned31BitInt' ;
3237const valueCursor : StackCursor < mixed > = createCursor(null);
33- const changedBitsCursor: StackCursor< number > = createCursor(0);
3438
3539let rendererSigil;
3640if (__DEV__) {
@@ -50,15 +54,13 @@ export function resetContextDependences(): void {
5054 lastContextWithAllBitsObserved = null ;
5155}
5256
53- export function pushProvider(providerFiber: Fiber, changedBits: number ): void {
54- const context : ReactContext < any > = providerFiber . type . _context ;
57+ export function pushProvider< T > (providerFiber: Fiber, nextValue: T ): void {
58+ const context : ReactContext < T > = providerFiber . type . _context ;
5559
5660 if ( isPrimaryRenderer ) {
57- push ( changedBitsCursor , context . _changedBits , providerFiber ) ;
5861 push ( valueCursor , context . _currentValue , providerFiber ) ;
5962
60- context . _currentValue = providerFiber . pendingProps . value ;
61- context . _changedBits = changedBits ;
63+ context . _currentValue = nextValue ;
6264 if ( __DEV__ ) {
6365 warningWithoutStack (
6466 context . _currentRenderer === undefined ||
@@ -70,11 +72,9 @@ export function pushProvider(providerFiber: Fiber, changedBits: number): void {
7072 context . _currentRenderer = rendererSigil ;
7173 }
7274 } else {
73- push ( changedBitsCursor , context . _changedBits2 , providerFiber ) ;
7475 push ( valueCursor , context . _currentValue2 , providerFiber ) ;
7576
76- context . _currentValue2 = providerFiber . pendingProps . value ;
77- context . _changedBits2 = changedBits ;
77+ context . _currentValue2 = nextValue ;
7878 if ( __DEV__ ) {
7979 warningWithoutStack (
8080 context . _currentRenderer2 === undefined ||
@@ -89,19 +89,15 @@ export function pushProvider(providerFiber: Fiber, changedBits: number): void {
8989}
9090
9191export function popProvider ( providerFiber : Fiber ) : void {
92- const changedBits = changedBitsCursor . current ;
9392 const currentValue = valueCursor . current ;
9493
9594 pop ( valueCursor , providerFiber ) ;
96- pop ( changedBitsCursor , providerFiber ) ;
9795
9896 const context : ReactContext < any > = providerFiber . type . _context ;
9997 if ( isPrimaryRenderer ) {
10098 context . _currentValue = currentValue ;
101- context . _changedBits = changedBits ;
10299 } else {
103100 context . _currentValue2 = currentValue ;
104- context . _changedBits2 = changedBits ;
105101 }
106102}
107103
@@ -162,6 +158,18 @@ export function propagateContextChange(
162158 ( dependency . observedBits & changedBits ) !== 0
163159 ) {
164160 // Match! Schedule an update on this fiber.
161+
162+ if ( fiber . tag === ClassComponent ) {
163+ // Schedule a force update on the work-in-progress.
164+ const update = createUpdate ( renderExpirationTime ) ;
165+ update . tag = ForceUpdate ;
166+ // TODO: Because we don't have a work-in-progress, this will add the
167+ // update to the current fiber, too, which means it will persist even if
168+ // this render is thrown away. Since it's a race condition, not sure it's
169+ // worth fixing.
170+ enqueueUpdate ( fiber , update ) ;
171+ }
172+
165173 if (
166174 fiber . expirationTime === NoWork ||
167175 fiber . expirationTime > renderExpirationTime
@@ -206,13 +214,8 @@ export function propagateContextChange(
206214 }
207215 node = node . return ;
208216 }
209- // Don't scan deeper than a matching consumer. When we render the
210- // consumer, we'll continue scanning from that point. This way the
211- // scanning work is time-sliced.
212- nextFiber = null ;
213- } else {
214- nextFiber = fiber . child ;
215217 }
218+ nextFiber = fiber . child ;
216219 dependency = dependency . next ;
217220 } while ( dependency !== null ) ;
218221 } else if ( fiber . tag === ContextProvider ) {
@@ -253,46 +256,13 @@ export function propagateContextChange(
253256export function prepareToReadContext (
254257 workInProgress : Fiber ,
255258 renderExpirationTime : ExpirationTime ,
256- ) : boolean {
259+ ) : void {
257260 currentlyRenderingFiber = workInProgress ;
258261 lastContextDependency = null ;
259262 lastContextWithAllBitsObserved = null ;
260263
261- const firstContextDependency = workInProgress . firstContextDependency ;
262- if ( firstContextDependency !== null ) {
263- // Reset the work-in-progress list
264- workInProgress . firstContextDependency = null ;
265-
266- // Iterate through the context dependencies and see if there were any
267- // changes. If so, continue propagating the context change by scanning
268- // the child subtree.
269- let dependency = firstContextDependency ;
270- let hasPendingContext = false ;
271- do {
272- const context = dependency . context ;
273- const changedBits = isPrimaryRenderer
274- ? context . _changedBits
275- : context . _changedBits2 ;
276- if ( changedBits !== 0 ) {
277- // Resume context change propagation. We need to call this even if
278- // this fiber bails out, in case deeply nested consumers observe more
279- // bits than this one.
280- propagateContextChange (
281- workInProgress ,
282- context ,
283- changedBits ,
284- renderExpirationTime ,
285- ) ;
286- if ( ( changedBits & dependency . observedBits ) !== 0 ) {
287- hasPendingContext = true ;
288- }
289- }
290- dependency = dependency . next ;
291- } while ( dependency !== null ) ;
292- return hasPendingContext ;
293- } else {
294- return false ;
295- }
264+ // Reset the work-in-progress list
265+ workInProgress . firstContextDependency = null ;
296266}
297267
298268export function readContext < T > (
0 commit comments