Remove support for passing badly typed elements to shallow renderer (#11442)

This commit is contained in:
Dan Abramov
2017-11-03 16:16:56 +00:00
committed by GitHub
parent e8a382343a
commit fd47129ce6
2 changed files with 46 additions and 11 deletions

View File

@@ -47,6 +47,7 @@ class ReactShallowRenderer {
'it by passing it to React.createElement.'
: '',
);
// Show a special message for host elements since it's a common case.
invariant(
typeof element.type !== 'string',
'ReactShallowRenderer render(): Shallow rendering works only with custom ' +
@@ -54,6 +55,14 @@ class ReactShallowRenderer {
'inspecting the rendered output, look at `el.props` directly instead.',
element.type,
);
invariant(
typeof element.type === 'function',
'ReactShallowRenderer render(): Shallow rendering works only with custom ' +
'components, but the provided element type was `%s`.',
Array.isArray(element.type)
? 'array'
: element.type === null ? 'null' : typeof element.type,
);
if (this._rendering) {
return;
@@ -144,12 +153,8 @@ class ReactShallowRenderer {
) {
this._instance.componentWillReceiveProps(props, context);
}
// Read state after cWRP in case it calls setState
// Fallback to previous instance state to support rendering React.cloneElement()
// TODO: the cloneElement() use case is broken and should be removed
// https://github.com/facebook/react/issues/11441
const state = this._newState || this._instance.state || emptyObject;
const state = this._newState || oldState;
let shouldUpdate = true;
if (this._forcedUpdate) {
@@ -161,9 +166,7 @@ class ReactShallowRenderer {
state,
context,
);
} else if (type && type.prototype && type.prototype.isPureReactComponent) {
// TODO: we can remove the type existence check when we fix this:
// https://github.com/facebook/react/issues/11441
} else if (type.prototype && type.prototype.isPureReactComponent) {
shouldUpdate =
!shallowEqual(oldProps, props) || !shallowEqual(oldState, state);
}

View File

@@ -844,12 +844,44 @@ describe('ReactShallowRenderer', () => {
}
const shallowRenderer = createRenderer();
let result = shallowRenderer.render(<SimpleComponent foo="foo" />);
const el = <SimpleComponent foo="foo" />;
let result = shallowRenderer.render(el);
expect(result).toEqual(<div>foo:bar</div>);
const instance = shallowRenderer.getMountedInstance();
const cloned = React.cloneElement(instance, {foo: 'baz'});
const cloned = React.cloneElement(el, {foo: 'baz'});
result = shallowRenderer.render(cloned);
expect(result).toEqual(<div>baz:bar</div>);
});
it('throws usefully when rendering badly-typed elements', () => {
spyOn(console, 'error');
const shallowRenderer = createRenderer();
var Undef = undefined;
expect(() => shallowRenderer.render(<Undef />)).toThrowError(
'ReactShallowRenderer render(): Shallow rendering works only with custom ' +
'components, but the provided element type was `undefined`.',
);
var Null = null;
expect(() => shallowRenderer.render(<Null />)).toThrowError(
'ReactShallowRenderer render(): Shallow rendering works only with custom ' +
'components, but the provided element type was `null`.',
);
var Arr = [];
expect(() => shallowRenderer.render(<Arr />)).toThrowError(
'ReactShallowRenderer render(): Shallow rendering works only with custom ' +
'components, but the provided element type was `array`.',
);
var Obj = {};
expect(() => shallowRenderer.render(<Obj />)).toThrowError(
'ReactShallowRenderer render(): Shallow rendering works only with custom ' +
'components, but the provided element type was `object`.',
);
// One warning for each element creation
expectDev(console.error.calls.count()).toBe(4);
});
});