@@ -49,6 +49,8 @@ let renderPhaseUpdates: Map<UpdateQueue<any>, Update<any>> | null = null;
4949let numberOfReRenders : number = 0 ;
5050const RE_RENDER_LIMIT = 25 ;
5151
52+ let shouldWarnAboutReadingContextInDEV = false ;
53+
5254// In DEV, this is the name of the currently executing primitive hook
5355let currentHookNameInDev : ?string ;
5456
@@ -137,6 +139,9 @@ function createWorkInProgressHook(): Hook {
137139
138140export function prepareToUseHooks ( componentIdentity : Object ) : void {
139141 currentlyRenderingComponent = componentIdentity ;
142+ if ( __DEV__ ) {
143+ shouldWarnAboutReadingContextInDEV = false ;
144+ }
140145
141146 // The following should have already been reset
142147 // didScheduleRenderPhaseUpdate = false;
@@ -173,6 +178,9 @@ export function finishHooks(
173178 numberOfReRenders = 0 ;
174179 renderPhaseUpdates = null ;
175180 workInProgressHook = null ;
181+ if ( __DEV__ ) {
182+ shouldWarnAboutReadingContextInDEV = false ;
183+ }
176184
177185 // These were reset above
178186 // currentlyRenderingComponent = null;
@@ -191,6 +199,15 @@ function readContext<T>(
191199): T {
192200 let threadID = currentThreadID ;
193201 validateContextBounds ( context , threadID ) ;
202+ if ( __DEV__ ) {
203+ warning (
204+ ! shouldWarnAboutReadingContextInDEV ,
205+ 'Context can only be read while React is rendering. ' +
206+ 'In classes, you can read it in the render method or getDerivedStateFromProps. ' +
207+ 'In function components, you can read it directly in the function body, but not ' +
208+ 'inside Hooks like useReducer() or useMemo().' ,
209+ ) ;
210+ }
194211 return context [ threadID ] ;
195212}
196213
@@ -255,7 +272,13 @@ export function useReducer<S, A>(
255272 const action = update . action ;
256273 // Temporarily clear to forbid calling Hooks.
257274 currentlyRenderingComponent = null ;
275+ if ( __DEV__ ) {
276+ shouldWarnAboutReadingContextInDEV = true ;
277+ }
258278 newState = reducer ( newState , action ) ;
279+ if ( __DEV__ ) {
280+ shouldWarnAboutReadingContextInDEV = false ;
281+ }
259282 currentlyRenderingComponent = component ;
260283 update = update . next ;
261284 } while ( update !== null ) ;
@@ -311,8 +334,14 @@ function useMemo<T>(nextCreate: () => T, deps: Array<mixed> | void | null): T {
311334
312335 // Temporarily clear to forbid calling Hooks.
313336 currentlyRenderingComponent = null ;
337+ if ( __DEV__ ) {
338+ shouldWarnAboutReadingContextInDEV = true ;
339+ }
314340 const nextValue = nextCreate();
315341 currentlyRenderingComponent = component;
342+ if (__DEV__) {
343+ shouldWarnAboutReadingContextInDEV = false ;
344+ }
316345 workInProgressHook.memoizedState = [nextValue, nextDeps];
317346 return nextValue;
318347}
0 commit comments