Skip to content

Commit 933157f

Browse files
committed
Don't warn outside of render
1 parent 959b279 commit 933157f

File tree

3 files changed

+118
-6
lines changed

3 files changed

+118
-6
lines changed

packages/react-dom/src/__tests__/ReactCompositeComponent-test.js

Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1749,4 +1749,114 @@ describe('ReactCompositeComponent', () => {
17491749
ReactDOM.render(<Shadow />, container);
17501750
expect(container.firstChild.tagName).toBe('DIV');
17511751
});
1752+
1753+
it('should not warn on updating function component from componentWillMount', () => {
1754+
let _setState;
1755+
function A() {
1756+
_setState = React.useState()[1];
1757+
return null;
1758+
}
1759+
class B extends React.Component {
1760+
UNSAFE_componentWillMount() {
1761+
_setState({});
1762+
}
1763+
render() {
1764+
return null;
1765+
}
1766+
}
1767+
function Parent() {
1768+
return (
1769+
<div>
1770+
<A />
1771+
<B />
1772+
</div>
1773+
);
1774+
}
1775+
const container = document.createElement('div');
1776+
ReactDOM.render(<Parent />, container);
1777+
});
1778+
1779+
it('should not warn on updating function component from componentWillUpdate', () => {
1780+
let _setState;
1781+
function A() {
1782+
_setState = React.useState()[1];
1783+
return null;
1784+
}
1785+
class B extends React.Component {
1786+
UNSAFE_componentWillUpdate() {
1787+
_setState({});
1788+
}
1789+
render() {
1790+
return null;
1791+
}
1792+
}
1793+
function Parent() {
1794+
return (
1795+
<div>
1796+
<A />
1797+
<B />
1798+
</div>
1799+
);
1800+
}
1801+
const container = document.createElement('div');
1802+
ReactDOM.render(<Parent />, container);
1803+
ReactDOM.render(<Parent />, container);
1804+
});
1805+
1806+
it('should not warn on updating function component from componentWillReceiveProps', () => {
1807+
let _setState;
1808+
function A() {
1809+
_setState = React.useState()[1];
1810+
return null;
1811+
}
1812+
class B extends React.Component {
1813+
UNSAFE_componentWillReceiveProps() {
1814+
_setState({});
1815+
}
1816+
render() {
1817+
return null;
1818+
}
1819+
}
1820+
function Parent() {
1821+
return (
1822+
<div>
1823+
<A />
1824+
<B />
1825+
</div>
1826+
);
1827+
}
1828+
const container = document.createElement('div');
1829+
ReactDOM.render(<Parent />, container);
1830+
ReactDOM.render(<Parent />, container);
1831+
});
1832+
1833+
it('should warn on updating function component from render', () => {
1834+
let _setState;
1835+
function A() {
1836+
_setState = React.useState()[1];
1837+
return null;
1838+
}
1839+
class B extends React.Component {
1840+
render() {
1841+
_setState({});
1842+
return null;
1843+
}
1844+
}
1845+
function Parent() {
1846+
return (
1847+
<div>
1848+
<A />
1849+
<B />
1850+
</div>
1851+
);
1852+
}
1853+
const container = document.createElement('div');
1854+
expect(() => {
1855+
ReactDOM.render(<Parent />, container);
1856+
}).toErrorDev(
1857+
'Cannot update a component (`A`) while rendering a different component (`B`)',
1858+
);
1859+
// Dedupe.
1860+
ReactDOM.render(<Parent />, container);
1861+
});
17521862
});

packages/react-reconciler/src/ReactFiberBeginWork.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1363,6 +1363,7 @@ function mountIndeterminateComponent(
13631363
ReactStrictModeWarnings.recordLegacyContextWarning(workInProgress, null);
13641364
}
13651365

1366+
setIsRendering(true);
13661367
ReactCurrentOwner.current = workInProgress;
13671368
value = renderWithHooks(
13681369
null,
@@ -1372,6 +1373,7 @@ function mountIndeterminateComponent(
13721373
context,
13731374
renderExpirationTime,
13741375
);
1376+
setIsRendering(false);
13751377
} else {
13761378
value = renderWithHooks(
13771379
null,

packages/react-reconciler/src/ReactFiberWorkLoop.js

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2927,7 +2927,10 @@ if (__DEV__) {
29272927

29282928
function warnAboutRenderPhaseUpdatesInDEV(fiber) {
29292929
if (__DEV__) {
2930-
if ((executionContext & RenderContext) !== NoContext) {
2930+
if (
2931+
ReactCurrentDebugFiberIsRenderingInDEV &&
2932+
(executionContext & RenderContext) !== NoContext
2933+
) {
29312934
switch (fiber.tag) {
29322935
case FunctionComponent:
29332936
case ForwardRef:
@@ -2953,18 +2956,15 @@ function warnAboutRenderPhaseUpdatesInDEV(fiber) {
29532956
break;
29542957
}
29552958
case ClassComponent: {
2956-
if (
2957-
ReactCurrentDebugFiberIsRenderingInDEV &&
2958-
!didWarnAboutUpdateInRender
2959-
) {
2959+
if (!didWarnAboutUpdateInRender) {
29602960
console.error(
29612961
'Cannot update during an existing state transition (such as ' +
29622962
'within `render`). Render methods should be a pure ' +
29632963
'function of props and state.',
29642964
);
29652965
didWarnAboutUpdateInRender = true;
2966-
break;
29672966
}
2967+
break;
29682968
}
29692969
}
29702970
}

0 commit comments

Comments
 (0)