Skip to content

Commit fbfaa53

Browse files
committed
Warn about rendering Generators
1 parent 46d5afc commit fbfaa53

File tree

2 files changed

+39
-0
lines changed

2 files changed

+39
-0
lines changed

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

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -294,6 +294,27 @@ describe('ReactMultiChild', () => {
294294
);
295295
});
296296

297+
it('should warn for using generators as children', () => {
298+
function* Foo() {
299+
yield <h1 key="1">Hello</h1>;
300+
yield <h1 key="2">World</h1>;
301+
}
302+
303+
const div = document.createElement('div');
304+
expect(() => {
305+
ReactDOM.render(<Foo />, div);
306+
}).toWarnDev(
307+
'Using Generators as children is unsupported and will likely yield ' +
308+
'unexpected results because enumerating a generator mutates it. You may ' +
309+
'convert it to an array with `Array.from()` or the `[...spread]` operator ' +
310+
'before rendering. Keep in mind you might need to polyfill these features for older browsers.\n' +
311+
' in Foo (at **)',
312+
);
313+
314+
// Test de-duplication
315+
ReactDOM.render(<Foo />, div);
316+
});
317+
297318
it('should reorder bailed-out children', () => {
298319
class LetterInner extends React.Component {
299320
render() {

packages/react-reconciler/src/ReactChildFiber.js

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,13 +46,15 @@ import {
4646
import {StrictMode} from './ReactTypeOfMode';
4747

4848
let didWarnAboutMaps;
49+
let didWarnAboutGenerators;
4950
let didWarnAboutStringRefInStrictMode;
5051
let ownerHasKeyUseWarning;
5152
let ownerHasFunctionTypeWarning;
5253
let warnForMissingKey = (child: mixed) => {};
5354

5455
if (__DEV__) {
5556
didWarnAboutMaps = false;
57+
didWarnAboutGenerators = false;
5658
didWarnAboutStringRefInStrictMode = {};
5759

5860
/**
@@ -903,6 +905,22 @@ function ChildReconciler(shouldTrackSideEffects) {
903905
);
904906

905907
if (__DEV__) {
908+
// We don't support rendering Generators because it's a mutation.
909+
// See https://github.com/facebook/react/issues/12995
910+
if (
911+
typeof Symbol === 'function' &&
912+
newChildrenIterable[Symbol.toStringTag] === 'Generator'
913+
) {
914+
warning(
915+
didWarnAboutGenerators,
916+
'Using Generators as children is unsupported and will likely yield ' +
917+
'unexpected results because enumerating a generator mutates it. ' +
918+
'You may convert it to an array with `Array.from()` or the `[...spread]` operator before rendering. Keep in mind ' +
919+
'you might need to polyfill these features for older browsers.',
920+
);
921+
didWarnAboutGenerators = true;
922+
}
923+
906924
// Warn about using Maps as children
907925
if ((newChildrenIterable: any).entries === iteratorFn) {
908926
warning(

0 commit comments

Comments
 (0)