mirror of
https://github.com/facebook/react.git
synced 2025-11-01 09:12:30 +00:00
Don't ignore dependencies for render phase update (#16574)
This commit is contained in:
@@ -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;
|
||||
|
||||
@@ -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(() => {
|
||||
|
||||
Reference in New Issue
Block a user