Fix React.createFactory() crash (#11484)
* Add a failing test for createFactory in production * Fix createFactory() in production * Add more prod-only tests * Fix prettier * Run prettier 1.8.1
Dan Abramov committed
Nov 8, 2017 at 00:02 UTC
c932885e7972a4d363a62127355ceeafe18829e8
2 files changed
+47
-1
packages/react-dom/src/__tests__/ReactDOMProduction-test.js
+46
@@ -93,6 +93,52 @@ describe('ReactDOMProduction', () => {
93
expect(container.childNodes.length).toBe(0);
94
});
95
96
+ it('should support createFactory', () => {
97
+ var span = React.createFactory('span');
98
+ class Component extends React.Component {
99
+ render() {
100
+ return span({children: this.props.children});
101
+ }
102
+ }
103
+
104
+ var ComponentFactory = React.createFactory(Component);
105
+
106
+ var container = document.createElement('div');
107
+ ReactDOM.render(
108
+ ComponentFactory(null, span(null, 'Hello'), span(null, 'world')),
109
+ container,
110
+ );
111
+ expect(container.firstChild.tagName).toBe('SPAN');
112
+ expect(container.firstChild.childNodes[0].tagName).toBe('SPAN');
113
+ expect(container.firstChild.childNodes[0].textContent).toBe('Hello');
114
+ expect(container.firstChild.childNodes[1].tagName).toBe('SPAN');
115
+ expect(container.firstChild.childNodes[1].textContent).toBe('world');
116
+ });
117
+
118
+ it('should support React public API methods', () => {
119
+ expect(React.isValidElement(42)).toBe(false);
120
+ expect(React.isValidElement(<div />)).toBe(true);
121
+ expect(React.cloneElement(<div />, {foo: 42})).toEqual(<div foo={42} />);
122
+
123
+ const mapped = React.Children.map(<div />, el =>
124
+ React.cloneElement(el, {foo: 42}),
125
+ );
126
+ expect(mapped.length).toBe(1);
127
+ expect(mapped[0].type).toBe('div');
128
+ expect(mapped[0].props.foo).toBe(42);
129
+
130
+ const arr = React.Children.toArray(<div />);
131
+ expect(arr.length).toBe(1);
132
+ expect(arr[0].type).toBe('div');
133
+
134
+ let called = 0;
135
+ React.Children.forEach(<div />, () => called++);
136
+ expect(called).toBe(1);
137
+
138
+ expect(React.Children.count(<div />)).toBe(1);
139
+ expect(() => React.Children.only(42)).toThrowError();
140
+ });
141
+
142
it('should handle a simple flow (ssr)', () => {
143
class Component extends React.Component {
144
render() {
packages/react/src/ReactElement.js
+1
-1
@@ -266,7 +266,7 @@ export function createElement(type, config, children) {
266
* See https://reactjs.org/docs/react-api.html#createfactory
267
*/
268
export function createFactory(type) {
269
- var factory = ReactElement.createElement.bind(null, type);
269
+ var factory = createElement.bind(null, type);
270
// Expose the type on the factory and the prototype so that it can be
271
// easily accessed on elements. E.g. `<Foo />.type === Foo`.
272
// This should not be named `constructor` since this may not be the function