@samitouri / QOS-React-2 / commits / 39b97e8eb8

Report refreshed families to the caller (#15957)

Dan Abramov committed Jun 22, 2019 at 23:57 UTC 39b97e8eb87b2b3b0d938660e1ac12223470fdf5
3 files changed +41 -9
packages/react-refresh/src/ReactFreshRuntime.js
+8 -7
@@ -142,10 +142,10 @@ function resolveFamily(type) {
142 return familiesByType.get(type);
143 }
144
145 -export function performReactRefresh(): boolean {
145 +export function performReactRefresh(): RefreshUpdate | null {
146 if (__DEV__) {
147 if (pendingUpdates.length === 0) {
148 - return false;
148 + return null;
149 }
150
151 const staleFamilies = new Set();
@@ -169,9 +169,10 @@ export function performReactRefresh(): boolean {
169 }
170 });
171
172 + // TODO: rename these fields to something more meaningful.
173 const update: RefreshUpdate = {
173 - updatedFamilies,
174 - staleFamilies,
174 + updatedFamilies, // Families that will re-render preserving state
175 + staleFamilies, // Families that will be remounted
176 };
177
178 if (typeof setRefreshHandler !== 'function') {
@@ -182,7 +183,7 @@ export function performReactRefresh(): boolean {
183 'called before the global DevTools hook was set up, or after the ' +
184 'renderer has already initialized. Please file an issue with a reproducing case.',
185 );
185 - return false;
186 + return null;
187 }
188
189 if (typeof scheduleRefresh !== 'function') {
@@ -193,7 +194,7 @@ export function performReactRefresh(): boolean {
194 'called before the global DevTools hook was set up, or after the ' +
195 'renderer has already initialized. Please file an issue with a reproducing case.',
196 );
196 - return false;
197 + return null;
198 }
199 const scheduleRefreshForRoot = scheduleRefresh;
200
@@ -217,7 +218,7 @@ export function performReactRefresh(): boolean {
218 if (didError) {
219 throw firstError;
220 }
220 - return true;
221 + return update;
222 } else {
223 throw new Error(
224 'Unexpected call to React Refresh in a production environment.',
packages/react-refresh/src/__tests__/ReactFresh-test.js
+31
@@ -3266,4 +3266,35 @@ describe('ReactFresh', () => {
3266 )(global, React, ReactFreshRuntime, expect, createReactClass);
3267 }
3268 });
3269 +
3270 + it('reports updated and remounted families to the caller', () => {
3271 + if (__DEV__) {
3272 + const HelloV1 = () => {
3273 + const [val, setVal] = React.useState(0);
3274 + return (
3275 + <p style={{color: 'blue'}} onClick={() => setVal(val + 1)}>
3276 + {val}
3277 + </p>
3278 + );
3279 + };
3280 + $RefreshReg$(HelloV1, 'Hello');
3281 +
3282 + const HelloV2 = () => {
3283 + const [val, setVal] = React.useState(0);
3284 + return (
3285 + <p style={{color: 'red'}} onClick={() => setVal(val + 1)}>
3286 + {val}
3287 + </p>
3288 + );
3289 + };
3290 + $RefreshReg$(HelloV2, 'Hello');
3291 +
3292 + const update = ReactFreshRuntime.performReactRefresh();
3293 + expect(update.updatedFamilies.size).toBe(1);
3294 + expect(update.staleFamilies.size).toBe(0);
3295 + const family = update.updatedFamilies.values().next().value;
3296 + expect(family.current.name).toBe('HelloV2');
3297 + // For example, we can use this to print a log of what was updated.
3298 + }
3299 + });
3300 });
packages/react-refresh/src/__tests__/ReactFreshIntegration-test.js
+2 -2
@@ -82,13 +82,13 @@ describe('ReactFreshIntegration', () => {
82 ReactDOM.render(<Component />, container);
83 });
84 // Module initialization shouldn't be counted as a hot update.
85 - expect(ReactFreshRuntime.performReactRefresh()).toBe(false);
85 + expect(ReactFreshRuntime.performReactRefresh()).toBe(null);
86 }
87
88 function patch(source) {
89 execute(source);
90 act(() => {
91 - expect(ReactFreshRuntime.performReactRefresh()).toBe(true);
91 + expect(ReactFreshRuntime.performReactRefresh()).not.toBe(null);
92 });
93 expect(ReactFreshRuntime._getMountedRootCount()).toBe(1);
94 }