Skip to content

Commit

Permalink
Don't ignore dependencies for render phase update (#16574)
Browse files Browse the repository at this point in the history
  • Loading branch information
gaearon authored Aug 28, 2019
1 parent 1b585f6 commit 01fb68b
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 0 deletions.
5 changes: 5 additions & 0 deletions packages/react-reconciler/src/ReactFiberHooks.js
Original file line number Diff line number Diff line change
Expand Up @@ -428,6 +428,11 @@ export function renderWithHooks(
do {
didScheduleRenderPhaseUpdate = false;
numberOfReRenders += 1;
if (__DEV__) {
// Even when hot reloading, allow dependencies to stabilize
// after first render to prevent infinite render phase updates.
ignorePreviousDependencies = false;
}

// Start over from the beginning of the list
nextCurrentHook = current !== null ? current.memoizedState : null;
Expand Down
43 changes: 43 additions & 0 deletions packages/react-refresh/src/__tests__/ReactFresh-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -2350,6 +2350,49 @@ describe('ReactFresh', () => {
}
});

// This pattern is inspired by useSubscription and similar mechanisms.
it('does not get into infinite loops during render phase updates', () => {
if (__DEV__) {
render(() => {
function Hello() {
const source = React.useMemo(() => ({value: 10}), []);
const [state, setState] = React.useState({value: null});
if (state !== source) {
setState(source);
}
return <p style={{color: 'blue'}}>{state.value}</p>;
}
$RefreshReg$(Hello, 'Hello');
return Hello;
});

const el = container.firstChild;
expect(el.textContent).toBe('10');
expect(el.style.color).toBe('blue');

// Perform a hot update.
act(() => {
patch(() => {
function Hello() {
const source = React.useMemo(() => ({value: 20}), []);
const [state, setState] = React.useState({value: null});
if (state !== source) {
// This should perform a single render-phase update.
setState(source);
}
return <p style={{color: 'red'}}>{state.value}</p>;
}
$RefreshReg$(Hello, 'Hello');
return Hello;
});
});

expect(container.firstChild).toBe(el);
expect(el.textContent).toBe('20');
expect(el.style.color).toBe('red');
}
});

it('can hot reload offscreen components', () => {
if (__DEV__) {
const AppV1 = prepare(() => {
Expand Down

0 comments on commit 01fb68b

Please sign in to comment.