diff --git a/packages/create-subscription/package.json b/packages/create-subscription/package.json
index aae1b59c78270..4677c731b7b53 100644
--- a/packages/create-subscription/package.json
+++ b/packages/create-subscription/package.json
@@ -1,7 +1,7 @@
{
"name": "create-subscription",
"description": "utility for subscribing to external data sources inside React components",
- "version": "16.13.1",
+ "version": "17.0.0-alpha.0",
"repository": {
"type": "git",
"url": "https://github.com/facebook/react.git",
@@ -15,7 +15,7 @@
"cjs/"
],
"peerDependencies": {
- "react": "^16.3.0"
+ "react": "^17.0.0-alpha"
},
"devDependencies": {
"rxjs": "^5.5.6"
diff --git a/packages/jest-react/package.json b/packages/jest-react/package.json
index 3876194096b54..2a1d8e8929d7d 100644
--- a/packages/jest-react/package.json
+++ b/packages/jest-react/package.json
@@ -1,6 +1,6 @@
{
"name": "jest-react",
- "version": "0.11.1",
+ "version": "0.12.0-alpha.0",
"description": "Jest matchers and utilities for testing React components.",
"main": "index.js",
"repository": {
@@ -20,8 +20,8 @@
"homepage": "https://reactjs.org/",
"peerDependencies": {
"jest": "^23.0.1 || ^24.0.0 || ^25.1.0",
- "react": "^16.0.0",
- "react-test-renderer": "^16.0.0"
+ "react": "^17.0.0-alpha",
+ "react-test-renderer": "^17.0.0-alpha"
},
"dependencies": {
"object-assign": "^4.1.1"
diff --git a/packages/react-art/package.json b/packages/react-art/package.json
index caaf4f3f93696..b611b4790fd81 100644
--- a/packages/react-art/package.json
+++ b/packages/react-art/package.json
@@ -1,7 +1,7 @@
{
"name": "react-art",
"description": "React ART is a JavaScript library for drawing vector graphics using React. It provides declarative and reactive bindings to the ART library. Using the same declarative API you can render the output to either Canvas, SVG or VML (IE8).",
- "version": "16.13.1",
+ "version": "17.0.0-alpha.0",
"main": "index.js",
"repository": {
"type": "git",
@@ -29,7 +29,7 @@
"scheduler": "^0.19.0"
},
"peerDependencies": {
- "react": "^16.13.0"
+ "react": "^17.0.0-alpha"
},
"files": [
"LICENSE",
diff --git a/packages/react-cache/package.json b/packages/react-cache/package.json
index b593f6d5811e1..56fb3d4dee090 100644
--- a/packages/react-cache/package.json
+++ b/packages/react-cache/package.json
@@ -17,6 +17,6 @@
"umd/"
],
"peerDependencies": {
- "react": "^16.3.0-alpha.1"
+ "react": "^17.0.0-alpha"
}
}
diff --git a/packages/react-client/package.json b/packages/react-client/package.json
index a0edddb8c3197..18cb2e872edb1 100644
--- a/packages/react-client/package.json
+++ b/packages/react-client/package.json
@@ -24,7 +24,7 @@
"node": ">=0.10.0"
},
"peerDependencies": {
- "react": "^16.0.0"
+ "react": "^17.0.0-alpha"
},
"dependencies": {
"loose-envify": "^1.1.0",
diff --git a/packages/react-debug-tools/package.json b/packages/react-debug-tools/package.json
index 0d69a5f55f509..e0ab8b93209c1 100644
--- a/packages/react-debug-tools/package.json
+++ b/packages/react-debug-tools/package.json
@@ -26,7 +26,7 @@
"node": ">=0.10.0"
},
"peerDependencies": {
- "react": "^16.0.0"
+ "react": "^17.0.0-alpha"
},
"dependencies": {
"error-stack-parser": "^2.0.2",
diff --git a/packages/react-devtools-shared/src/__tests__/profilingCache-test.js b/packages/react-devtools-shared/src/__tests__/profilingCache-test.js
index 817becdc0d0eb..476b073843e09 100644
--- a/packages/react-devtools-shared/src/__tests__/profilingCache-test.js
+++ b/packages/react-devtools-shared/src/__tests__/profilingCache-test.js
@@ -716,4 +716,93 @@ describe('ProfilingCache', () => {
TestRenderer.create( );
});
});
+
+ // See https://github.com/facebook/react/issues/18831
+ it('should not crash during route transitions with Suspense', () => {
+ const RouterContext = React.createContext();
+
+ function App() {
+ return (
+
+
+
+
+
+
+
+
+
+
+ );
+ }
+
+ const Home = () => {
+ return (
+
+ Home
+
+ );
+ };
+
+ const About = () =>
hello, world.
;
- }
- }
-
- const handler = jest.fn().mockName('spy');
- const shallowRenderer = ReactShallowRenderer.createRenderer();
- const result = shallowRenderer.render(
- {}}
- onClick={this.handleUserClick}
- className={this.state.clicked ? 'clicked' : ''}
- />
- );
- }
- }
-
- const shallowRenderer = createRenderer();
- shallowRenderer.render(
);
- let result = shallowRenderer.getRenderOutput();
- expect(result.type).toEqual('div');
- expect(result.props.className).toEqual('');
- result.props.onClick();
-
- result = shallowRenderer.getRenderOutput();
- expect(result.type).toEqual('div');
- expect(result.props.className).toEqual('clicked');
- });
-
- it('can initialize state via static getDerivedStateFromProps', () => {
- class SimpleComponent extends React.Component {
- state = {
- count: 1,
- };
-
- static getDerivedStateFromProps(props, prevState) {
- return {
- count: prevState.count + props.incrementBy,
- other: 'foobar',
- };
- }
-
- render() {
- return (
-
{`count:${this.state.count}, other:${this.state.other}`}
- );
- }
- }
-
- const shallowRenderer = createRenderer();
- const result = shallowRenderer.render(
);
- expect(result).toEqual(
count:3, other:foobar
);
- });
-
- it('can setState in componentWillMount when shallow rendering', () => {
- class SimpleComponent extends React.Component {
- UNSAFE_componentWillMount() {
- this.setState({groovy: 'doovy'});
- }
-
- render() {
- return
{this.state.groovy}
;
- }
- }
-
- const shallowRenderer = createRenderer();
- const result = shallowRenderer.render(
);
- expect(result).toEqual(
doovy
);
- });
-
- it('can setState in componentWillMount repeatedly when shallow rendering', () => {
- class SimpleComponent extends React.Component {
- state = {
- separator: '-',
- };
-
- UNSAFE_componentWillMount() {
- this.setState({groovy: 'doovy'});
- this.setState({doovy: 'groovy'});
- }
-
- render() {
- const {groovy, doovy, separator} = this.state;
-
- return
{`${groovy}${separator}${doovy}`}
;
- }
- }
-
- const shallowRenderer = createRenderer();
- const result = shallowRenderer.render(
);
- expect(result).toEqual(
doovy-groovy
);
- });
-
- it('can setState in componentWillMount with an updater function repeatedly when shallow rendering', () => {
- class SimpleComponent extends React.Component {
- state = {
- separator: '-',
- };
-
- UNSAFE_componentWillMount() {
- this.setState(state => ({groovy: 'doovy'}));
- this.setState(state => ({doovy: state.groovy}));
- }
-
- render() {
- const {groovy, doovy, separator} = this.state;
-
- return
{`${groovy}${separator}${doovy}`}
;
- }
- }
-
- const shallowRenderer = createRenderer();
- const result = shallowRenderer.render(
);
- expect(result).toEqual(
doovy-doovy
);
- });
-
- it('can setState in componentWillReceiveProps when shallow rendering', () => {
- class SimpleComponent extends React.Component {
- state = {count: 0};
-
- UNSAFE_componentWillReceiveProps(nextProps) {
- if (nextProps.updateState) {
- this.setState({count: 1});
- }
- }
-
- render() {
- return
{this.state.count}
;
- }
- }
-
- const shallowRenderer = createRenderer();
- let result = shallowRenderer.render(
-
,
- );
- expect(result.props.children).toEqual(0);
-
- result = shallowRenderer.render(
);
- expect(result.props.children).toEqual(1);
- });
-
- it('can update state with static getDerivedStateFromProps when shallow rendering', () => {
- class SimpleComponent extends React.Component {
- state = {count: 1};
-
- static getDerivedStateFromProps(nextProps, prevState) {
- if (nextProps.updateState) {
- return {count: nextProps.incrementBy + prevState.count};
- }
-
- return null;
- }
-
- render() {
- return
{this.state.count}
;
- }
- }
-
- const shallowRenderer = createRenderer();
- let result = shallowRenderer.render(
-
,
- );
- expect(result.props.children).toEqual(1);
-
- result = shallowRenderer.render(
-
,
- );
- expect(result.props.children).toEqual(3);
-
- result = shallowRenderer.render(
-
,
- );
- expect(result.props.children).toEqual(3);
- });
-
- it('should not override state with stale values if prevState is spread within getDerivedStateFromProps', () => {
- class SimpleComponent extends React.Component {
- state = {value: 0};
-
- static getDerivedStateFromProps(nextProps, prevState) {
- return {...prevState};
- }
-
- updateState = () => {
- this.setState(state => ({value: state.value + 1}));
- };
-
- render() {
- return
{`value:${this.state.value}`}
;
- }
- }
-
- const shallowRenderer = createRenderer();
- let result = shallowRenderer.render(
);
- expect(result).toEqual(
value:0
);
-
- const instance = shallowRenderer.getMountedInstance();
- instance.updateState();
- result = shallowRenderer.getRenderOutput();
- expect(result).toEqual(
value:1
);
- });
-
- it('should pass previous state to shouldComponentUpdate even with getDerivedStateFromProps', () => {
- class SimpleComponent extends React.Component {
- constructor(props) {
- super(props);
- this.state = {
- value: props.value,
- };
- }
-
- static getDerivedStateFromProps(nextProps, prevState) {
- if (nextProps.value === prevState.value) {
- return null;
- }
- return {value: nextProps.value};
- }
-
- shouldComponentUpdate(nextProps, nextState) {
- return nextState.value !== this.state.value;
- }
-
- render() {
- return
{`value:${this.state.value}`}
;
- }
- }
-
- const shallowRenderer = createRenderer();
- const initialResult = shallowRenderer.render(
-
,
- );
- expect(initialResult).toEqual(
value:initial
);
- const updatedResult = shallowRenderer.render(
-
,
- );
- expect(updatedResult).toEqual(
value:updated
);
- });
-
- it('can setState with an updater function', () => {
- let instance;
-
- class SimpleComponent extends React.Component {
- state = {
- counter: 0,
- };
-
- render() {
- instance = this;
- return (
-
- {this.state.counter}
-
- );
- }
- }
-
- const shallowRenderer = createRenderer();
- let result = shallowRenderer.render(
);
- expect(result.props.children).toEqual(0);
-
- instance.setState((state, props) => {
- return {counter: props.defaultCount + 1};
- });
-
- result = shallowRenderer.getRenderOutput();
- expect(result.props.children).toEqual(2);
- });
-
- it('can access component instance from setState updater function', done => {
- let instance;
-
- class SimpleComponent extends React.Component {
- state = {};
-
- render() {
- instance = this;
- return null;
- }
- }
-
- const shallowRenderer = createRenderer();
- shallowRenderer.render(
);
-
- instance.setState(function updater(state, props) {
- expect(this).toBe(instance);
- done();
- });
- });
-
- it('can setState with a callback', () => {
- let instance;
-
- class SimpleComponent extends React.Component {
- state = {
- counter: 0,
- };
- render() {
- instance = this;
- return
{this.state.counter}
;
- }
- }
-
- const shallowRenderer = createRenderer();
- const result = shallowRenderer.render(
);
- expect(result.props.children).toBe(0);
-
- const callback = jest.fn(function() {
- expect(this).toBe(instance);
- });
-
- instance.setState({counter: 1}, callback);
-
- const updated = shallowRenderer.getRenderOutput();
- expect(updated.props.children).toBe(1);
- expect(callback).toHaveBeenCalled();
- });
-
- it('can replaceState with a callback', () => {
- let instance;
-
- class SimpleComponent extends React.Component {
- state = {
- counter: 0,
- };
- render() {
- instance = this;
- return
{this.state.counter}
;
- }
- }
-
- const shallowRenderer = createRenderer();
- const result = shallowRenderer.render(
);
- expect(result.props.children).toBe(0);
-
- const callback = jest.fn(function() {
- expect(this).toBe(instance);
- });
-
- // No longer a public API, but we can test that it works internally by
- // reaching into the updater.
- shallowRenderer._updater.enqueueReplaceState(
- instance,
- {counter: 1},
- callback,
- );
-
- const updated = shallowRenderer.getRenderOutput();
- expect(updated.props.children).toBe(1);
- expect(callback).toHaveBeenCalled();
- });
-
- it('can forceUpdate with a callback', () => {
- let instance;
-
- class SimpleComponent extends React.Component {
- state = {
- counter: 0,
- };
- render() {
- instance = this;
- return
{this.state.counter}
;
- }
- }
-
- const shallowRenderer = createRenderer();
- const result = shallowRenderer.render(
);
- expect(result.props.children).toBe(0);
-
- const callback = jest.fn(function() {
- expect(this).toBe(instance);
- });
-
- instance.forceUpdate(callback);
-
- const updated = shallowRenderer.getRenderOutput();
- expect(updated.props.children).toBe(0);
- expect(callback).toHaveBeenCalled();
- });
-
- it('can pass context when shallowly rendering', () => {
- class SimpleComponent extends React.Component {
- static contextTypes = {
- name: PropTypes.string,
- };
-
- render() {
- return
{this.context.name}
;
- }
- }
-
- const shallowRenderer = createRenderer();
- const result = shallowRenderer.render(
, {
- name: 'foo',
- });
- expect(result).toEqual(
foo
);
- });
-
- it('should track context across updates', () => {
- class SimpleComponent extends React.Component {
- static contextTypes = {
- foo: PropTypes.string,
- };
-
- state = {
- bar: 'bar',
- };
-
- render() {
- return
{`${this.context.foo}:${this.state.bar}`}
;
- }
- }
-
- const shallowRenderer = createRenderer();
- let result = shallowRenderer.render(
, {
- foo: 'foo',
- });
- expect(result).toEqual(
foo:bar
);
-
- const instance = shallowRenderer.getMountedInstance();
- instance.setState({bar: 'baz'});
-
- result = shallowRenderer.getRenderOutput();
- expect(result).toEqual(
foo:baz
);
- });
-
- it('should filter context by contextTypes', () => {
- class SimpleComponent extends React.Component {
- static contextTypes = {
- foo: PropTypes.string,
- };
- render() {
- return
{`${this.context.foo}:${this.context.bar}`}
;
- }
- }
-
- const shallowRenderer = createRenderer();
- const result = shallowRenderer.render(
, {
- foo: 'foo',
- bar: 'bar',
- });
- expect(result).toEqual(
foo:undefined
);
- });
-
- it('can fail context when shallowly rendering', () => {
- class SimpleComponent extends React.Component {
- static contextTypes = {
- name: PropTypes.string.isRequired,
- };
-
- render() {
- return
{this.context.name}
;
- }
- }
-
- const shallowRenderer = createRenderer();
- expect(() => shallowRenderer.render(
)).toErrorDev(
- 'Warning: Failed context type: The context `name` is marked as ' +
- 'required in `SimpleComponent`, but its value is `undefined`.\n' +
- ' in SimpleComponent (at **)',
- );
- });
-
- it('should warn about propTypes (but only once)', () => {
- class SimpleComponent extends React.Component {
- render() {
- return React.createElement('div', null, this.props.name);
- }
- }
-
- SimpleComponent.propTypes = {
- name: PropTypes.string.isRequired,
- };
-
- const shallowRenderer = createRenderer();
- expect(() =>
- shallowRenderer.render(React.createElement(SimpleComponent, {name: 123})),
- ).toErrorDev(
- 'Warning: Failed prop type: Invalid prop `name` of type `number` ' +
- 'supplied to `SimpleComponent`, expected `string`.\n' +
- ' in SimpleComponent',
- );
- });
-
- it('should enable rendering of cloned element', () => {
- class SimpleComponent extends React.Component {
- constructor(props) {
- super(props);
-
- this.state = {
- bar: 'bar',
- };
- }
-
- render() {
- return
{`${this.props.foo}:${this.state.bar}`}
;
- }
- }
-
- const shallowRenderer = createRenderer();
- const el =
;
- let result = shallowRenderer.render(el);
- expect(result).toEqual(
foo:bar
);
-
- const cloned = React.cloneElement(el, {foo: 'baz'});
- result = shallowRenderer.render(cloned);
- expect(result).toEqual(
baz:bar
);
- });
-
- it('this.state should be updated on setState callback inside componentWillMount', () => {
- let stateSuccessfullyUpdated = false;
-
- class Component extends React.Component {
- constructor(props, context) {
- super(props, context);
- this.state = {
- hasUpdatedState: false,
- };
- }
-
- UNSAFE_componentWillMount() {
- this.setState(
- {hasUpdatedState: true},
- () => (stateSuccessfullyUpdated = this.state.hasUpdatedState),
- );
- }
-
- render() {
- return
{this.props.children}
;
- }
- }
-
- const shallowRenderer = createRenderer();
- shallowRenderer.render(
);
- expect(stateSuccessfullyUpdated).toBe(true);
- });
-
- it('should handle multiple callbacks', () => {
- const mockFn = jest.fn();
- const shallowRenderer = createRenderer();
-
- class Component extends React.Component {
- constructor(props, context) {
- super(props, context);
- this.state = {
- foo: 'foo',
- };
- }
-
- UNSAFE_componentWillMount() {
- this.setState({foo: 'bar'}, () => mockFn());
- this.setState({foo: 'foobar'}, () => mockFn());
- }
-
- render() {
- return
{this.state.foo}
;
- }
- }
-
- shallowRenderer.render(
);
-
- expect(mockFn).toHaveBeenCalledTimes(2);
-
- // Ensure the callback queue is cleared after the callbacks are invoked
- const mountedInstance = shallowRenderer.getMountedInstance();
- mountedInstance.setState({foo: 'bar'}, () => mockFn());
- expect(mockFn).toHaveBeenCalledTimes(3);
- });
-
- it('should call the setState callback even if shouldComponentUpdate = false', done => {
- const mockFn = jest.fn().mockReturnValue(false);
-
- class Component extends React.Component {
- constructor(props, context) {
- super(props, context);
- this.state = {
- hasUpdatedState: false,
- };
- }
-
- shouldComponentUpdate() {
- return mockFn();
- }
-
- render() {
- return
{this.state.hasUpdatedState}
;
- }
- }
-
- const shallowRenderer = createRenderer();
- shallowRenderer.render(
);
-
- const mountedInstance = shallowRenderer.getMountedInstance();
- mountedInstance.setState({hasUpdatedState: true}, () => {
- expect(mockFn).toBeCalled();
- expect(mountedInstance.state.hasUpdatedState).toBe(true);
- done();
- });
- });
-
- it('throws usefully when rendering badly-typed elements', () => {
- const shallowRenderer = createRenderer();
-
- const renderAndVerifyWarningAndError = (Component, typeString) => {
- expect(() => {
- expect(() => shallowRenderer.render(
)).toErrorDev(
- 'React.createElement: type is invalid -- expected a string ' +
- '(for built-in components) or a class/function (for composite components) ' +
- `but got: ${typeString}.`,
- );
- }).toThrowError(
- 'ReactShallowRenderer render(): Shallow rendering works only with custom ' +
- `components, but the provided element type was \`${typeString}\`.`,
- );
- };
-
- renderAndVerifyWarningAndError(undefined, 'undefined');
- renderAndVerifyWarningAndError(null, 'null');
- renderAndVerifyWarningAndError([], 'array');
- renderAndVerifyWarningAndError({}, 'object');
- });
-
- it('should have initial state of null if not defined', () => {
- class SomeComponent extends React.Component {
- render() {
- return
;
- }
- }
-
- const shallowRenderer = createRenderer();
- shallowRenderer.render(
);
-
- expect(shallowRenderer.getMountedInstance().state).toBeNull();
- });
-
- it('should invoke both deprecated and new lifecycles if both are present', () => {
- const log = [];
-
- class Component extends React.Component {
- componentWillMount() {
- log.push('componentWillMount');
- }
- componentWillReceiveProps() {
- log.push('componentWillReceiveProps');
- }
- componentWillUpdate() {
- log.push('componentWillUpdate');
- }
- UNSAFE_componentWillMount() {
- log.push('UNSAFE_componentWillMount');
- }
- UNSAFE_componentWillReceiveProps() {
- log.push('UNSAFE_componentWillReceiveProps');
- }
- UNSAFE_componentWillUpdate() {
- log.push('UNSAFE_componentWillUpdate');
- }
- render() {
- return null;
- }
- }
-
- const shallowRenderer = createRenderer();
- shallowRenderer.render(
);
- expect(log).toEqual(['componentWillMount', 'UNSAFE_componentWillMount']);
-
- log.length = 0;
-
- shallowRenderer.render(
);
- expect(log).toEqual([
- 'componentWillReceiveProps',
- 'UNSAFE_componentWillReceiveProps',
- 'componentWillUpdate',
- 'UNSAFE_componentWillUpdate',
- ]);
- });
-
- it('should stop the update when setState returns null or undefined', () => {
- const log = [];
- let instance;
- class Component extends React.Component {
- constructor(props) {
- super(props);
- this.state = {
- count: 0,
- };
- }
- render() {
- log.push('render');
- instance = this;
- return null;
- }
- }
- const shallowRenderer = createRenderer();
- shallowRenderer.render(
);
- log.length = 0;
- instance.setState(() => null);
- instance.setState(() => undefined);
- instance.setState(null);
- instance.setState(undefined);
- expect(log).toEqual([]);
- instance.setState(state => ({count: state.count + 1}));
- expect(log).toEqual(['render']);
- });
-
- it('should not get this in a function component', () => {
- const logs = [];
- function Foo() {
- logs.push(this);
- return
foo
;
- }
- const shallowRenderer = createRenderer();
- shallowRenderer.render(
);
- expect(logs).toEqual([undefined]);
- });
-
- it('should handle memo', () => {
- function Foo() {
- return
foo
;
- }
- const MemoFoo = React.memo(Foo);
- const shallowRenderer = createRenderer();
- shallowRenderer.render(
);
- });
-
- it('should enable React.memo to prevent a re-render', () => {
- const logs = [];
- const Foo = React.memo(({count}) => {
- logs.push(`Foo: ${count}`);
- return
{count}
;
- });
- const Bar = React.memo(({count}) => {
- logs.push(`Bar: ${count}`);
- return
{count}
;
- });
- const shallowRenderer = createRenderer();
- shallowRenderer.render(
);
- expect(logs).toEqual(['Foo: 1']);
- logs.length = 0;
- // Rendering the same element with the same props should be prevented
- shallowRenderer.render(
);
- expect(logs).toEqual([]);
- // A different element with the same props should cause a re-render
- shallowRenderer.render(
);
- expect(logs).toEqual(['Bar: 1']);
- });
-
- it('should respect a custom comparison function with React.memo', () => {
- let renderCount = 0;
- function areEqual(props, nextProps) {
- return props.foo === nextProps.foo;
- }
- const Foo = React.memo(({foo, bar}) => {
- renderCount++;
- return (
-
- {foo} {bar}
-
- );
- }, areEqual);
-
- const shallowRenderer = createRenderer();
- shallowRenderer.render(
);
- expect(renderCount).toBe(1);
- // Change a prop that the comparison function ignores
- shallowRenderer.render(
);
- expect(renderCount).toBe(1);
- shallowRenderer.render(
);
- expect(renderCount).toBe(2);
- });
-
- it('should not call the comparison function with React.memo on the initial render', () => {
- const areEqual = jest.fn(() => false);
- const SomeComponent = React.memo(({foo}) => {
- return
{foo}
;
- }, areEqual);
- const shallowRenderer = createRenderer();
- shallowRenderer.render(
);
- expect(areEqual).not.toHaveBeenCalled();
- expect(shallowRenderer.getRenderOutput()).toEqual(
{1}
);
- });
-
- it('should handle memo(forwardRef())', () => {
- const testRef = React.createRef();
- const SomeComponent = React.forwardRef((props, ref) => {
- expect(ref).toEqual(testRef);
- return (
-
-
-
-
- );
- });
-
- const SomeMemoComponent = React.memo(SomeComponent);
-
- const shallowRenderer = createRenderer();
- const result = shallowRenderer.render(
);
-
- expect(result.type).toBe('div');
- expect(result.props.children).toEqual([
-
,
-
,
- ]);
- });
-
- it('should warn for forwardRef(memo())', () => {
- const testRef = React.createRef();
- const SomeMemoComponent = React.memo(({foo}) => {
- return
{foo}
;
- });
- const shallowRenderer = createRenderer();
- expect(() => {
- expect(() => {
- const SomeComponent = React.forwardRef(SomeMemoComponent);
- shallowRenderer.render(
);
- }).toErrorDev(
- 'Warning: forwardRef requires a render function but received ' +
- 'a `memo` component. Instead of forwardRef(memo(...)), use ' +
- 'memo(forwardRef(...))',
- {withoutStack: true},
- );
- }).toThrowError(
- 'forwardRef requires a render function but was given object.',
- );
- });
-
- it('should let you change type', () => {
- function Foo({prop}) {
- return
Foo {prop}
;
- }
- function Bar({prop}) {
- return
Bar {prop}
;
- }
-
- const shallowRenderer = createRenderer();
- shallowRenderer.render(
);
- expect(shallowRenderer.getRenderOutput()).toEqual(
Foo {'foo1'}
);
- shallowRenderer.render(
);
- expect(shallowRenderer.getRenderOutput()).toEqual(
Foo {'foo2'}
);
- shallowRenderer.render(
);
- expect(shallowRenderer.getRenderOutput()).toEqual(
Bar {'bar1'}
);
- shallowRenderer.render(
);
- expect(shallowRenderer.getRenderOutput()).toEqual(
Bar {'bar2'}
);
- });
-
- it('should let you change class type', () => {
- class Foo extends React.Component {
- render() {
- return
Foo {this.props.prop}
;
- }
- }
- class Bar extends React.Component {
- render() {
- return
Bar {this.props.prop}
;
- }
- }
-
- const shallowRenderer = createRenderer();
- shallowRenderer.render(
);
- expect(shallowRenderer.getRenderOutput()).toEqual(
Foo {'foo1'}
);
- shallowRenderer.render(
);
- expect(shallowRenderer.getRenderOutput()).toEqual(
Foo {'foo2'}
);
- shallowRenderer.render(
);
- expect(shallowRenderer.getRenderOutput()).toEqual(
Bar {'bar1'}
);
- shallowRenderer.render(
);
- expect(shallowRenderer.getRenderOutput()).toEqual(
Bar {'bar2'}
);
- });
-});
diff --git a/packages/react-test-renderer/src/__tests__/ReactShallowRendererHooks-test.js b/packages/react-test-renderer/src/__tests__/ReactShallowRendererHooks-test.js
deleted file mode 100644
index 811768f2a0c13..0000000000000
--- a/packages/react-test-renderer/src/__tests__/ReactShallowRendererHooks-test.js
+++ /dev/null
@@ -1,487 +0,0 @@
-/**
- * Copyright (c) Facebook, Inc. and its affiliates.
- *
- * This source code is licensed under the MIT license found in the
- * LICENSE file in the root directory of this source tree.
- *
- * @emails react-core
- * @jest-environment node
- */
-
-'use strict';
-
-import * as React from 'react';
-import ReactShallowRenderer from 'react-test-renderer/shallow';
-
-const createRenderer = ReactShallowRenderer.createRenderer;
-
-describe('ReactShallowRenderer with hooks', () => {
- it('should work with useState', () => {
- function SomeComponent({defaultName}) {
- const [name] = React.useState(defaultName);
-
- return (
-
-
- Your name is: {name}
-
-
- );
- }
-
- const shallowRenderer = createRenderer();
- let result = shallowRenderer.render(
-
,
- );
-
- expect(result).toEqual(
-
-
- Your name is: Dominic
-
-
,
- );
-
- result = shallowRenderer.render(
-
,
- );
-
- expect(result).toEqual(
-
-
- Your name is: Dominic
-
-
,
- );
- });
-
- it('should work with updating a value from useState', () => {
- function SomeComponent({defaultName}) {
- const [name, updateName] = React.useState(defaultName);
-
- if (name !== 'Dan') {
- updateName('Dan');
- }
-
- return (
-
-
- Your name is: {name}
-
-
- );
- }
-
- const shallowRenderer = createRenderer();
- const result = shallowRenderer.render(
-
,
- );
-
- expect(result).toEqual(
-
-
- Your name is: Dan
-
-
,
- );
- });
-
- it('should work with updating a derived value from useState', () => {
- let _updateName;
-
- function SomeComponent({defaultName}) {
- const [name, updateName] = React.useState(defaultName);
- const [prevName, updatePrevName] = React.useState(defaultName);
- const [letter, updateLetter] = React.useState(name[0]);
-
- _updateName = updateName;
-
- if (name !== prevName) {
- updatePrevName(name);
- updateLetter(name[0]);
- }
-
- return (
-
-
- Your name is: {name + ' (' + letter + ')'}
-
-
- );
- }
-
- const shallowRenderer = createRenderer();
- let result = shallowRenderer.render(
-
,
- );
- expect(result).toEqual(
-
-
- Your name is: Sophie (S)
-
-
,
- );
-
- result = shallowRenderer.render(
);
- expect(result).toEqual(
-
-
- Your name is: Sophie (S)
-
-
,
- );
-
- _updateName('Dan');
- expect(shallowRenderer.getRenderOutput()).toEqual(
-
-
- Your name is: Dan (D)
-
-
,
- );
- });
-
- it('should work with useReducer', () => {
- function reducer(state, action) {
- switch (action.type) {
- case 'increment':
- return {count: state.count + 1};
- case 'decrement':
- return {count: state.count - 1};
- }
- }
-
- function SomeComponent(props) {
- const [state] = React.useReducer(reducer, props, p => ({
- count: p.initialCount,
- }));
-
- return (
-
-
- The counter is at: {state.count.toString()}
-
-
- );
- }
-
- const shallowRenderer = createRenderer();
- let result = shallowRenderer.render(
);
-
- expect(result).toEqual(
-
-
- The counter is at: 0
-
-
,
- );
-
- result = shallowRenderer.render(
);
-
- expect(result).toEqual(
-
-
- The counter is at: 0
-
-
,
- );
- });
-
- it('should work with a dispatched state change for a useReducer', () => {
- function reducer(state, action) {
- switch (action.type) {
- case 'increment':
- return {count: state.count + 1};
- case 'decrement':
- return {count: state.count - 1};
- }
- }
-
- function SomeComponent(props) {
- const [state, dispatch] = React.useReducer(reducer, props, p => ({
- count: p.initialCount,
- }));
-
- if (state.count === 0) {
- dispatch({type: 'increment'});
- }
-
- return (
-
-
- The counter is at: {state.count.toString()}
-
-
- );
- }
-
- const shallowRenderer = createRenderer();
- const result = shallowRenderer.render(
);
-
- expect(result).toEqual(
-
-
- The counter is at: 1
-
-
,
- );
- });
-
- it('should not trigger effects', () => {
- const effectsCalled = [];
-
- function SomeComponent({defaultName}) {
- React.useEffect(() => {
- effectsCalled.push('useEffect');
- });
-
- React.useLayoutEffect(() => {
- effectsCalled.push('useEffect');
- });
-
- return
Hello world
;
- }
-
- const shallowRenderer = createRenderer();
- shallowRenderer.render(
);
-
- expect(effectsCalled).toEqual([]);
- });
-
- it('should work with useRef', () => {
- function SomeComponent() {
- const randomNumberRef = React.useRef({number: Math.random()});
-
- return (
-
-
The random number is: {randomNumberRef.current.number}
-
- );
- }
-
- const shallowRenderer = createRenderer();
- const firstResult = shallowRenderer.render(
);
- const secondResult = shallowRenderer.render(
);
-
- expect(firstResult).toEqual(secondResult);
- });
-
- it('should work with useMemo', () => {
- function SomeComponent() {
- const randomNumber = React.useMemo(() => {
- return {number: Math.random()};
- }, []);
-
- return (
-
-
The random number is: {randomNumber.number}
-
- );
- }
-
- const shallowRenderer = createRenderer();
- const firstResult = shallowRenderer.render(
);
- const secondResult = shallowRenderer.render(
);
-
- expect(firstResult).toEqual(secondResult);
- });
-
- it('should work with useContext', () => {
- const SomeContext = React.createContext('default');
-
- function SomeComponent() {
- const value = React.useContext(SomeContext);
-
- return (
-
- );
- }
-
- const shallowRenderer = createRenderer();
- const result = shallowRenderer.render(
);
-
- expect(result).toEqual(
-
,
- );
- });
-
- it('should not leak state when component type changes', () => {
- function SomeComponent({defaultName}) {
- const [name] = React.useState(defaultName);
-
- return (
-
-
- Your name is: {name}
-
-
- );
- }
-
- function SomeOtherComponent({defaultName}) {
- const [name] = React.useState(defaultName);
-
- return (
-
-
- Your name is: {name}
-
-
- );
- }
-
- const shallowRenderer = createRenderer();
- let result = shallowRenderer.render(
-
,
- );
- expect(result).toEqual(
-
-
- Your name is: Dominic
-
-
,
- );
-
- result = shallowRenderer.render(
);
- expect(result).toEqual(
-
-
- Your name is: Dan
-
-
,
- );
- });
-
- it('should work with with forwardRef + any hook', () => {
- const SomeComponent = React.forwardRef((props, ref) => {
- const randomNumberRef = React.useRef({number: Math.random()});
-
- return (
-
-
The random number is: {randomNumberRef.current.number}
-
- );
- });
-
- const shallowRenderer = createRenderer();
- const firstResult = shallowRenderer.render(
);
- const secondResult = shallowRenderer.render(
);
-
- expect(firstResult).toEqual(secondResult);
- });
-
- it('should update a value from useState outside the render', () => {
- let _dispatch;
-
- function SomeComponent({defaultName}) {
- const [count, dispatch] = React.useReducer(
- (s, a) => (a === 'inc' ? s + 1 : s),
- 0,
- );
- const [name, updateName] = React.useState(defaultName);
- _dispatch = () => dispatch('inc');
-
- return (
-
updateName('Dan')}>
-
- Your name is: {name} ({count})
-
-
- );
- }
-
- const shallowRenderer = createRenderer();
- const element =
;
- const result = shallowRenderer.render(element);
- expect(result.props.children).toEqual(
-
- Your name is: Dominic ({0})
-
,
- );
-
- result.props.onClick();
- let updated = shallowRenderer.render(element);
- expect(updated.props.children).toEqual(
-
- Your name is: Dan ({0})
-
,
- );
-
- _dispatch('foo');
- updated = shallowRenderer.render(element);
- expect(updated.props.children).toEqual(
-
- Your name is: Dan ({1})
-
,
- );
-
- _dispatch('inc');
- updated = shallowRenderer.render(element);
- expect(updated.props.children).toEqual(
-
- Your name is: Dan ({2})
-
,
- );
- });
-
- it('should ignore a foreign update outside the render', () => {
- let _updateCountForFirstRender;
-
- function SomeComponent() {
- const [count, updateCount] = React.useState(0);
- if (!_updateCountForFirstRender) {
- _updateCountForFirstRender = updateCount;
- }
- return count;
- }
-
- const shallowRenderer = createRenderer();
- const element =
;
- let result = shallowRenderer.render(element);
- expect(result).toEqual(0);
- _updateCountForFirstRender(1);
- result = shallowRenderer.render(element);
- expect(result).toEqual(1);
-
- shallowRenderer.unmount();
- result = shallowRenderer.render(element);
- expect(result).toEqual(0);
- _updateCountForFirstRender(1); // Should be ignored.
- result = shallowRenderer.render(element);
- expect(result).toEqual(0);
- });
-
- it('should not forget render phase updates', () => {
- let _updateCount;
-
- function SomeComponent() {
- const [count, updateCount] = React.useState(0);
- _updateCount = updateCount;
- if (count < 5) {
- updateCount(x => x + 1);
- }
- return count;
- }
-
- const shallowRenderer = createRenderer();
- const element =
;
- let result = shallowRenderer.render(element);
- expect(result).toEqual(5);
-
- _updateCount(10);
- result = shallowRenderer.render(element);
- expect(result).toEqual(10);
-
- _updateCount(x => x + 1);
- result = shallowRenderer.render(element);
- expect(result).toEqual(11);
-
- _updateCount(x => x - 10);
- result = shallowRenderer.render(element);
- expect(result).toEqual(5);
- });
-});
diff --git a/packages/react-test-renderer/src/__tests__/ReactShallowRendererMemo-test.js b/packages/react-test-renderer/src/__tests__/ReactShallowRendererMemo-test.js
deleted file mode 100644
index a0c0f7fc46139..0000000000000
--- a/packages/react-test-renderer/src/__tests__/ReactShallowRendererMemo-test.js
+++ /dev/null
@@ -1,1514 +0,0 @@
-/**
- * Copyright (c) Facebook, Inc. and its affiliates.
- *
- * This source code is licensed under the MIT license found in the
- * LICENSE file in the root directory of this source tree.
- *
- * @emails react-core
- * @jest-environment node
- */
-
-'use strict';
-
-import * as PropTypes from 'prop-types';
-import * as React from 'react';
-import ReactShallowRenderer from 'react-test-renderer/shallow';
-
-const createRenderer = ReactShallowRenderer.createRenderer;
-
-describe('ReactShallowRendererMemo', () => {
- it('should call all of the legacy lifecycle hooks', () => {
- const logs = [];
- const logger = message => () => logs.push(message) || true;
-
- const SomeComponent = React.memo(
- class SomeComponent extends React.Component {
- UNSAFE_componentWillMount = logger('componentWillMount');
- componentDidMount = logger('componentDidMount');
- UNSAFE_componentWillReceiveProps = logger('componentWillReceiveProps');
- shouldComponentUpdate = logger('shouldComponentUpdate');
- UNSAFE_componentWillUpdate = logger('componentWillUpdate');
- componentDidUpdate = logger('componentDidUpdate');
- componentWillUnmount = logger('componentWillUnmount');
- render() {
- return
;
- }
- },
- );
-
- const shallowRenderer = createRenderer();
- shallowRenderer.render(
);
-
- // Calling cDU might lead to problems with host component references.
- // Since our components aren't really mounted, refs won't be available.
- expect(logs).toEqual(['componentWillMount']);
-
- logs.splice(0);
-
- const instance = shallowRenderer.getMountedInstance();
- instance.setState({});
-
- expect(logs).toEqual(['shouldComponentUpdate', 'componentWillUpdate']);
-
- logs.splice(0);
-
- shallowRenderer.render(
);
-
- // The previous shallow renderer did not trigger cDU for props changes.
- expect(logs).toEqual([
- 'componentWillReceiveProps',
- 'shouldComponentUpdate',
- 'componentWillUpdate',
- ]);
- });
-
- it('should call all of the new lifecycle hooks', () => {
- const logs = [];
- const logger = message => () => logs.push(message) || true;
-
- const SomeComponent = React.memo(
- class SomeComponent extends React.Component {
- state = {};
- static getDerivedStateFromProps = logger('getDerivedStateFromProps');
- componentDidMount = logger('componentDidMount');
- shouldComponentUpdate = logger('shouldComponentUpdate');
- componentDidUpdate = logger('componentDidUpdate');
- componentWillUnmount = logger('componentWillUnmount');
- render() {
- return
;
- }
- },
- );
-
- const shallowRenderer = createRenderer();
- shallowRenderer.render(
);
-
- // Calling cDU might lead to problems with host component references.
- // Since our components aren't really mounted, refs won't be available.
- expect(logs).toEqual(['getDerivedStateFromProps']);
-
- logs.splice(0);
-
- const instance = shallowRenderer.getMountedInstance();
- instance.setState({});
-
- expect(logs).toEqual(['getDerivedStateFromProps', 'shouldComponentUpdate']);
-
- logs.splice(0);
-
- shallowRenderer.render(
);
-
- // The previous shallow renderer did not trigger cDU for props changes.
- expect(logs).toEqual(['getDerivedStateFromProps', 'shouldComponentUpdate']);
- });
-
- it('should not invoke deprecated lifecycles (cWM/cWRP/cWU) if new static gDSFP is present', () => {
- const Component = React.memo(
- class Component extends React.Component {
- state = {};
- static getDerivedStateFromProps() {
- return null;
- }
- componentWillMount() {
- throw Error('unexpected');
- }
- componentWillReceiveProps() {
- throw Error('unexpected');
- }
- componentWillUpdate() {
- throw Error('unexpected');
- }
- render() {
- return null;
- }
- },
- );
-
- const shallowRenderer = createRenderer();
- shallowRenderer.render(
);
- });
-
- it('should not invoke deprecated lifecycles (cWM/cWRP/cWU) if new getSnapshotBeforeUpdate is present', () => {
- const Component = React.memo(
- class Component extends React.Component {
- getSnapshotBeforeUpdate() {
- return null;
- }
- componentWillMount() {
- throw Error('unexpected');
- }
- componentWillReceiveProps() {
- throw Error('unexpected');
- }
- componentWillUpdate() {
- throw Error('unexpected');
- }
- render() {
- return null;
- }
- },
- );
-
- const shallowRenderer = createRenderer();
- shallowRenderer.render(
);
- shallowRenderer.render(
);
- });
-
- it('should not call getSnapshotBeforeUpdate or componentDidUpdate when updating since refs wont exist', () => {
- const Component = React.memo(
- class Component extends React.Component {
- getSnapshotBeforeUpdate() {
- throw Error('unexpected');
- }
- componentDidUpdate() {
- throw Error('unexpected');
- }
- render() {
- return null;
- }
- },
- );
-
- const shallowRenderer = createRenderer();
- shallowRenderer.render(
);
- shallowRenderer.render(
);
- });
-
- it('should only render 1 level deep', () => {
- const Parent = React.memo(function Parent() {
- return (
-
-
-
- );
- });
-
- function Child() {
- throw Error('This component should not render');
- }
-
- const shallowRenderer = createRenderer();
- shallowRenderer.render(React.createElement(Parent));
- });
-
- it('should have shallow rendering', () => {
- const SomeComponent = React.memo(
- class SomeComponent extends React.Component {
- render() {
- return (
-
-
-
-
- );
- }
- },
- );
-
- const shallowRenderer = createRenderer();
- const result = shallowRenderer.render(
);
-
- expect(result.type).toBe('div');
- expect(result.props.children).toEqual([
-
,
-
,
- ]);
- });
-
- it('should handle Profiler', () => {
- const SomeComponent = React.memo(
- class SomeComponent extends React.Component {
- render() {
- return (
-
-
-
-
-
-
- );
- }
- },
- );
-
- const shallowRenderer = createRenderer();
- const result = shallowRenderer.render(
);
-
- expect(result.type).toBe(React.Profiler);
- expect(result.props.children).toEqual(
-
-
-
-
,
- );
- });
-
- it('should enable shouldComponentUpdate to prevent a re-render', () => {
- let renderCounter = 0;
- const SimpleComponent = React.memo(
- class SimpleComponent extends React.Component {
- state = {update: false};
- shouldComponentUpdate(nextProps, nextState) {
- return this.state.update !== nextState.update;
- }
- render() {
- renderCounter++;
- return
{`${renderCounter}`}
;
- }
- },
- );
-
- const shallowRenderer = createRenderer();
- shallowRenderer.render(
);
- expect(shallowRenderer.getRenderOutput()).toEqual(
1
);
-
- const instance = shallowRenderer.getMountedInstance();
- instance.setState({update: false});
- expect(shallowRenderer.getRenderOutput()).toEqual(
1
);
-
- instance.setState({update: true});
- expect(shallowRenderer.getRenderOutput()).toEqual(
2
);
- });
-
- it('should enable PureComponent to prevent a re-render', () => {
- let renderCounter = 0;
- const SimpleComponent = React.memo(
- class SimpleComponent extends React.PureComponent {
- state = {update: false};
- render() {
- renderCounter++;
- return
{`${renderCounter}`}
;
- }
- },
- );
-
- const shallowRenderer = createRenderer();
- shallowRenderer.render(
);
- expect(shallowRenderer.getRenderOutput()).toEqual(
1
);
-
- const instance = shallowRenderer.getMountedInstance();
- instance.setState({update: false});
- expect(shallowRenderer.getRenderOutput()).toEqual(
1
);
-
- instance.setState({update: true});
- expect(shallowRenderer.getRenderOutput()).toEqual(
2
);
- });
-
- it('should not run shouldComponentUpdate during forced update', () => {
- let scuCounter = 0;
- const SimpleComponent = React.memo(
- class SimpleComponent extends React.Component {
- state = {count: 1};
- shouldComponentUpdate() {
- scuCounter++;
- return false;
- }
- render() {
- return
{`${this.state.count}`}
;
- }
- },
- );
-
- const shallowRenderer = createRenderer();
- shallowRenderer.render(
);
- expect(scuCounter).toEqual(0);
- expect(shallowRenderer.getRenderOutput()).toEqual(
1
);
-
- // Force update the initial state. sCU should not fire.
- const instance = shallowRenderer.getMountedInstance();
- instance.forceUpdate();
- expect(scuCounter).toEqual(0);
- expect(shallowRenderer.getRenderOutput()).toEqual(
1
);
-
- // Setting state updates the instance, but doesn't re-render
- // because sCU returned false.
- instance.setState(state => ({count: state.count + 1}));
- expect(scuCounter).toEqual(1);
- expect(instance.state.count).toEqual(2);
- expect(shallowRenderer.getRenderOutput()).toEqual(
1
);
-
- // A force update updates the render output, but doesn't call sCU.
- instance.forceUpdate();
- expect(scuCounter).toEqual(1);
- expect(instance.state.count).toEqual(2);
- expect(shallowRenderer.getRenderOutput()).toEqual(
2
);
- });
-
- it('should rerender when calling forceUpdate', () => {
- let renderCounter = 0;
- const SimpleComponent = React.memo(
- class SimpleComponent extends React.Component {
- render() {
- renderCounter += 1;
- return
;
- }
- },
- );
-
- const shallowRenderer = createRenderer();
- shallowRenderer.render(
);
- expect(renderCounter).toEqual(1);
-
- const instance = shallowRenderer.getMountedInstance();
- instance.forceUpdate();
- expect(renderCounter).toEqual(2);
- });
-
- it('should shallow render a function component', () => {
- function SomeComponent(props, context) {
- return (
-
-
{props.foo}
-
{context.bar}
-
-
-
- );
- }
- const SomeMemoComponent = React.memo(SomeComponent);
-
- SomeComponent.contextTypes = {
- bar: PropTypes.string,
- };
-
- const shallowRenderer = createRenderer();
- const result = shallowRenderer.render(
, {
- bar: 'BAR',
- });
-
- expect(result.type).toBe('div');
- expect(result.props.children).toEqual([
-
FOO
,
-
BAR
,
-
,
-
,
- ]);
- });
-
- it('should shallow render a component returning strings directly from render', () => {
- const Text = React.memo(({value}) => value);
-
- const shallowRenderer = createRenderer();
- const result = shallowRenderer.render(
);
- expect(result).toEqual('foo');
- });
-
- it('should shallow render a component returning numbers directly from render', () => {
- const Text = React.memo(({value}) => value);
-
- const shallowRenderer = createRenderer();
- const result = shallowRenderer.render(
);
- expect(result).toEqual(10);
- });
-
- it('should shallow render a fragment', () => {
- class SomeComponent extends React.Component {
- render() {
- return
;
- }
- }
- class Fragment extends React.Component {
- render() {
- return [
,
,
];
- }
- }
- const shallowRenderer = createRenderer();
- const result = shallowRenderer.render(
);
- expect(result).toEqual([
-
,
-
,
-
,
- ]);
- });
-
- it('should shallow render a React.fragment', () => {
- class SomeComponent extends React.Component {
- render() {
- return
;
- }
- }
- class Fragment extends React.Component {
- render() {
- return (
- <>
-
-
-
- >
- );
- }
- }
- const shallowRenderer = createRenderer();
- const result = shallowRenderer.render(
);
- expect(result).toEqual(
- <>
-
-
-
- >,
- );
- });
-
- it('should throw for invalid elements', () => {
- class SomeComponent extends React.Component {
- render() {
- return
;
- }
- }
-
- const shallowRenderer = createRenderer();
- expect(() => shallowRenderer.render(SomeComponent)).toThrowError(
- 'ReactShallowRenderer render(): Invalid component element. Instead of ' +
- 'passing a component class, make sure to instantiate it by passing it ' +
- 'to React.createElement.',
- );
- expect(() => shallowRenderer.render(
)).toThrowError(
- 'ReactShallowRenderer render(): Shallow rendering works only with ' +
- 'custom components, not primitives (div). Instead of calling ' +
- '`.render(el)` and inspecting the rendered output, look at `el.props` ' +
- 'directly instead.',
- );
- });
-
- it('should have shallow unmounting', () => {
- const componentWillUnmount = jest.fn();
-
- class SomeComponent extends React.Component {
- componentWillUnmount = componentWillUnmount;
- render() {
- return
;
- }
- }
-
- const shallowRenderer = createRenderer();
- shallowRenderer.render(
);
- shallowRenderer.unmount();
-
- expect(componentWillUnmount).toBeCalled();
- });
-
- it('can shallow render to null', () => {
- class SomeComponent extends React.Component {
- render() {
- return null;
- }
- }
-
- const shallowRenderer = createRenderer();
- const result = shallowRenderer.render(
);
-
- expect(result).toBe(null);
- });
-
- it('can shallow render with a ref', () => {
- class SomeComponent extends React.Component {
- render() {
- return
;
- }
- }
-
- const shallowRenderer = createRenderer();
- // Shouldn't crash.
- shallowRenderer.render(
);
- });
-
- it('lets you update shallowly rendered components', () => {
- class SomeComponent extends React.Component {
- state = {clicked: false};
-
- onClick = () => {
- this.setState({clicked: true});
- };
-
- render() {
- const className = this.state.clicked ? 'was-clicked' : '';
-
- if (this.props.aNew === 'prop') {
- return (
-
- Test link
-
- );
- } else {
- return (
-
-
-
-
- );
- }
- }
- }
-
- const shallowRenderer = createRenderer();
- const result = shallowRenderer.render(
);
- expect(result.type).toBe('div');
- expect(result.props.children).toEqual([
-
,
-
,
- ]);
-
- const updatedResult = shallowRenderer.render(
);
- expect(updatedResult.type).toBe('a');
-
- const mockEvent = {};
- updatedResult.props.onClick(mockEvent);
-
- const updatedResultCausedByClick = shallowRenderer.getRenderOutput();
- expect(updatedResultCausedByClick.type).toBe('a');
- expect(updatedResultCausedByClick.props.className).toBe('was-clicked');
- });
-
- it('can access the mounted component instance', () => {
- const SimpleComponent = React.memo(
- class SimpleComponent extends React.Component {
- someMethod = () => {
- return this.props.n;
- };
-
- render() {
- return
{this.props.n}
;
- }
- },
- );
-
- const shallowRenderer = createRenderer();
- shallowRenderer.render(
);
- expect(shallowRenderer.getMountedInstance().someMethod()).toEqual(5);
- });
-
- it('can shallowly render components with contextTypes', () => {
- const SimpleComponent = React.memo(
- class SimpleComponent extends React.Component {
- static contextTypes = {
- name: PropTypes.string,
- };
-
- render() {
- return
;
- }
- },
- );
-
- const shallowRenderer = createRenderer();
- const result = shallowRenderer.render(
);
- expect(result).toEqual(
);
- });
-
- it('passes expected params to legacy component lifecycle methods', () => {
- const componentDidUpdateParams = [];
- const componentWillReceivePropsParams = [];
- const componentWillUpdateParams = [];
- const setStateParams = [];
- const shouldComponentUpdateParams = [];
-
- const initialProp = {prop: 'init prop'};
- const initialState = {state: 'init state'};
- const initialContext = {context: 'init context'};
- const updatedState = {state: 'updated state'};
- const updatedProp = {prop: 'updated prop'};
- const updatedContext = {context: 'updated context'};
-
- const SimpleComponent = React.memo(
- class SimpleComponent extends React.Component {
- constructor(props, context) {
- super(props, context);
- this.state = initialState;
- }
- static contextTypes = {
- context: PropTypes.string,
- };
- componentDidUpdate(...args) {
- componentDidUpdateParams.push(...args);
- }
- UNSAFE_componentWillReceiveProps(...args) {
- componentWillReceivePropsParams.push(...args);
- this.setState((...innerArgs) => {
- setStateParams.push(...innerArgs);
- return updatedState;
- });
- }
- UNSAFE_componentWillUpdate(...args) {
- componentWillUpdateParams.push(...args);
- }
- shouldComponentUpdate(...args) {
- shouldComponentUpdateParams.push(...args);
- return true;
- }
- render() {
- return null;
- }
- },
- );
-
- const shallowRenderer = createRenderer();
- shallowRenderer.render(
- React.createElement(SimpleComponent, initialProp),
- initialContext,
- );
- expect(componentDidUpdateParams).toEqual([]);
- expect(componentWillReceivePropsParams).toEqual([]);
- expect(componentWillUpdateParams).toEqual([]);
- expect(setStateParams).toEqual([]);
- expect(shouldComponentUpdateParams).toEqual([]);
-
- // Lifecycle hooks should be invoked with the correct prev/next params on update.
- shallowRenderer.render(
- React.createElement(SimpleComponent, updatedProp),
- updatedContext,
- );
- expect(componentWillReceivePropsParams).toEqual([
- updatedProp,
- updatedContext,
- ]);
- expect(setStateParams).toEqual([initialState, initialProp]);
- expect(shouldComponentUpdateParams).toEqual([
- updatedProp,
- updatedState,
- updatedContext,
- ]);
- expect(componentWillUpdateParams).toEqual([
- updatedProp,
- updatedState,
- updatedContext,
- ]);
- expect(componentDidUpdateParams).toEqual([]);
- });
-
- it('passes expected params to new component lifecycle methods', () => {
- const componentDidUpdateParams = [];
- const getDerivedStateFromPropsParams = [];
- const shouldComponentUpdateParams = [];
-
- const initialProp = {prop: 'init prop'};
- const initialState = {state: 'init state'};
- const initialContext = {context: 'init context'};
- const updatedProp = {prop: 'updated prop'};
- const updatedContext = {context: 'updated context'};
-
- const SimpleComponent = React.memo(
- class SimpleComponent extends React.Component {
- constructor(props, context) {
- super(props, context);
- this.state = initialState;
- }
- static contextTypes = {
- context: PropTypes.string,
- };
- componentDidUpdate(...args) {
- componentDidUpdateParams.push(...args);
- }
- static getDerivedStateFromProps(...args) {
- getDerivedStateFromPropsParams.push(args);
- return null;
- }
- shouldComponentUpdate(...args) {
- shouldComponentUpdateParams.push(...args);
- return true;
- }
- render() {
- return null;
- }
- },
- );
-
- const shallowRenderer = createRenderer();
-
- // The only lifecycle hook that should be invoked on initial render
- // Is the static getDerivedStateFromProps() methods
- shallowRenderer.render(
- React.createElement(SimpleComponent, initialProp),
- initialContext,
- );
- expect(getDerivedStateFromPropsParams).toEqual([
- [initialProp, initialState],
- ]);
- expect(componentDidUpdateParams).toEqual([]);
- expect(shouldComponentUpdateParams).toEqual([]);
-
- // Lifecycle hooks should be invoked with the correct prev/next params on update.
- shallowRenderer.render(
- React.createElement(SimpleComponent, updatedProp),
- updatedContext,
- );
- expect(getDerivedStateFromPropsParams).toEqual([
- [initialProp, initialState],
- [updatedProp, initialState],
- ]);
- expect(shouldComponentUpdateParams).toEqual([
- updatedProp,
- initialState,
- updatedContext,
- ]);
- expect(componentDidUpdateParams).toEqual([]);
- });
-
- it('can shallowly render components with ref as function', () => {
- const SimpleComponent = React.memo(
- class SimpleComponent extends React.Component {
- state = {clicked: false};
-
- handleUserClick = () => {
- this.setState({clicked: true});
- };
-
- render() {
- return (
-
{}}
- onClick={this.handleUserClick}
- className={this.state.clicked ? 'clicked' : ''}
- />
- );
- }
- },
- );
-
- const shallowRenderer = createRenderer();
- shallowRenderer.render(
);
- let result = shallowRenderer.getRenderOutput();
- expect(result.type).toEqual('div');
- expect(result.props.className).toEqual('');
- result.props.onClick();
-
- result = shallowRenderer.getRenderOutput();
- expect(result.type).toEqual('div');
- expect(result.props.className).toEqual('clicked');
- });
-
- it('can initialize state via static getDerivedStateFromProps', () => {
- const SimpleComponent = React.memo(
- class SimpleComponent extends React.Component {
- state = {
- count: 1,
- };
-
- static getDerivedStateFromProps(props, prevState) {
- return {
- count: prevState.count + props.incrementBy,
- other: 'foobar',
- };
- }
-
- render() {
- return (
-
{`count:${this.state.count}, other:${this.state.other}`}
- );
- }
- },
- );
-
- const shallowRenderer = createRenderer();
- const result = shallowRenderer.render(
);
- expect(result).toEqual(
count:3, other:foobar
);
- });
-
- it('can setState in componentWillMount when shallow rendering', () => {
- const SimpleComponent = React.memo(
- class SimpleComponent extends React.Component {
- UNSAFE_componentWillMount() {
- this.setState({groovy: 'doovy'});
- }
-
- render() {
- return
{this.state.groovy}
;
- }
- },
- );
-
- const shallowRenderer = createRenderer();
- const result = shallowRenderer.render(
);
- expect(result).toEqual(
doovy
);
- });
-
- it('can setState in componentWillMount repeatedly when shallow rendering', () => {
- const SimpleComponent = React.memo(
- class SimpleComponent extends React.Component {
- state = {
- separator: '-',
- };
-
- UNSAFE_componentWillMount() {
- this.setState({groovy: 'doovy'});
- this.setState({doovy: 'groovy'});
- }
-
- render() {
- const {groovy, doovy, separator} = this.state;
-
- return
{`${groovy}${separator}${doovy}`}
;
- }
- },
- );
-
- const shallowRenderer = createRenderer();
- const result = shallowRenderer.render(
);
- expect(result).toEqual(
doovy-groovy
);
- });
-
- it('can setState in componentWillMount with an updater function repeatedly when shallow rendering', () => {
- const SimpleComponent = React.memo(
- class SimpleComponent extends React.Component {
- state = {
- separator: '-',
- };
-
- UNSAFE_componentWillMount() {
- this.setState(state => ({groovy: 'doovy'}));
- this.setState(state => ({doovy: state.groovy}));
- }
-
- render() {
- const {groovy, doovy, separator} = this.state;
-
- return
{`${groovy}${separator}${doovy}`}
;
- }
- },
- );
-
- const shallowRenderer = createRenderer();
- const result = shallowRenderer.render(
);
- expect(result).toEqual(
doovy-doovy
);
- });
-
- it('can setState in componentWillReceiveProps when shallow rendering', () => {
- const SimpleComponent = React.memo(
- class SimpleComponent extends React.Component {
- state = {count: 0};
-
- UNSAFE_componentWillReceiveProps(nextProps) {
- if (nextProps.updateState) {
- this.setState({count: 1});
- }
- }
-
- render() {
- return
{this.state.count}
;
- }
- },
- );
-
- const shallowRenderer = createRenderer();
- let result = shallowRenderer.render(
-
,
- );
- expect(result.props.children).toEqual(0);
-
- result = shallowRenderer.render(
);
- expect(result.props.children).toEqual(1);
- });
-
- it('can update state with static getDerivedStateFromProps when shallow rendering', () => {
- const SimpleComponent = React.memo(
- class SimpleComponent extends React.Component {
- state = {count: 1};
-
- static getDerivedStateFromProps(nextProps, prevState) {
- if (nextProps.updateState) {
- return {count: nextProps.incrementBy + prevState.count};
- }
-
- return null;
- }
-
- render() {
- return
{this.state.count}
;
- }
- },
- );
-
- const shallowRenderer = createRenderer();
- let result = shallowRenderer.render(
-
,
- );
- expect(result.props.children).toEqual(1);
-
- result = shallowRenderer.render(
-
,
- );
- expect(result.props.children).toEqual(3);
-
- result = shallowRenderer.render(
-
,
- );
- expect(result.props.children).toEqual(3);
- });
-
- it('should not override state with stale values if prevState is spread within getDerivedStateFromProps', () => {
- const SimpleComponent = React.memo(
- class SimpleComponent extends React.Component {
- state = {value: 0};
-
- static getDerivedStateFromProps(nextProps, prevState) {
- return {...prevState};
- }
-
- updateState = () => {
- this.setState(state => ({value: state.value + 1}));
- };
-
- render() {
- return
{`value:${this.state.value}`}
;
- }
- },
- );
-
- const shallowRenderer = createRenderer();
- let result = shallowRenderer.render(
);
- expect(result).toEqual(
value:0
);
-
- const instance = shallowRenderer.getMountedInstance();
- instance.updateState();
- result = shallowRenderer.getRenderOutput();
- expect(result).toEqual(
value:1
);
- });
-
- it('should pass previous state to shouldComponentUpdate even with getDerivedStateFromProps', () => {
- const SimpleComponent = React.memo(
- class SimpleComponent extends React.Component {
- constructor(props) {
- super(props);
- this.state = {
- value: props.value,
- };
- }
-
- static getDerivedStateFromProps(nextProps, prevState) {
- if (nextProps.value === prevState.value) {
- return null;
- }
- return {value: nextProps.value};
- }
-
- shouldComponentUpdate(nextProps, nextState) {
- return nextState.value !== this.state.value;
- }
-
- render() {
- return
{`value:${this.state.value}`}
;
- }
- },
- );
-
- const shallowRenderer = createRenderer();
- const initialResult = shallowRenderer.render(
-
,
- );
- expect(initialResult).toEqual(
value:initial
);
- const updatedResult = shallowRenderer.render(
-
,
- );
- expect(updatedResult).toEqual(
value:updated
);
- });
-
- it('can setState with an updater function', () => {
- let instance;
-
- const SimpleComponent = React.memo(
- class SimpleComponent extends React.Component {
- state = {
- counter: 0,
- };
-
- render() {
- instance = this;
- return (
-
- {this.state.counter}
-
- );
- }
- },
- );
-
- const shallowRenderer = createRenderer();
- let result = shallowRenderer.render(
);
- expect(result.props.children).toEqual(0);
-
- instance.setState((state, props) => {
- return {counter: props.defaultCount + 1};
- });
-
- result = shallowRenderer.getRenderOutput();
- expect(result.props.children).toEqual(2);
- });
-
- it('can access component instance from setState updater function', done => {
- let instance;
-
- const SimpleComponent = React.memo(
- class SimpleComponent extends React.Component {
- state = {};
-
- render() {
- instance = this;
- return null;
- }
- },
- );
-
- const shallowRenderer = createRenderer();
- shallowRenderer.render(
);
-
- instance.setState(function updater(state, props) {
- expect(this).toBe(instance);
- done();
- });
- });
-
- it('can setState with a callback', () => {
- let instance;
-
- const SimpleComponent = React.memo(
- class SimpleComponent extends React.Component {
- state = {
- counter: 0,
- };
- render() {
- instance = this;
- return
{this.state.counter}
;
- }
- },
- );
-
- const shallowRenderer = createRenderer();
- const result = shallowRenderer.render(
);
- expect(result.props.children).toBe(0);
-
- const callback = jest.fn(function() {
- expect(this).toBe(instance);
- });
-
- instance.setState({counter: 1}, callback);
-
- const updated = shallowRenderer.getRenderOutput();
- expect(updated.props.children).toBe(1);
- expect(callback).toHaveBeenCalled();
- });
-
- it('can replaceState with a callback', () => {
- let instance;
-
- const SimpleComponent = React.memo(
- class SimpleComponent extends React.Component {
- state = {
- counter: 0,
- };
- render() {
- instance = this;
- return
{this.state.counter}
;
- }
- },
- );
-
- const shallowRenderer = createRenderer();
- const result = shallowRenderer.render(
);
- expect(result.props.children).toBe(0);
-
- const callback = jest.fn(function() {
- expect(this).toBe(instance);
- });
-
- // No longer a public API, but we can test that it works internally by
- // reaching into the updater.
- shallowRenderer._updater.enqueueReplaceState(
- instance,
- {counter: 1},
- callback,
- );
-
- const updated = shallowRenderer.getRenderOutput();
- expect(updated.props.children).toBe(1);
- expect(callback).toHaveBeenCalled();
- });
-
- it('can forceUpdate with a callback', () => {
- let instance;
-
- const SimpleComponent = React.memo(
- class SimpleComponent extends React.Component {
- state = {
- counter: 0,
- };
- render() {
- instance = this;
- return
{this.state.counter}
;
- }
- },
- );
-
- const shallowRenderer = createRenderer();
- const result = shallowRenderer.render(
);
- expect(result.props.children).toBe(0);
-
- const callback = jest.fn(function() {
- expect(this).toBe(instance);
- });
-
- instance.forceUpdate(callback);
-
- const updated = shallowRenderer.getRenderOutput();
- expect(updated.props.children).toBe(0);
- expect(callback).toHaveBeenCalled();
- });
-
- it('can pass context when shallowly rendering', () => {
- const SimpleComponent = React.memo(
- class SimpleComponent extends React.Component {
- static contextTypes = {
- name: PropTypes.string,
- };
-
- render() {
- return
{this.context.name}
;
- }
- },
- );
-
- const shallowRenderer = createRenderer();
- const result = shallowRenderer.render(
, {
- name: 'foo',
- });
- expect(result).toEqual(
foo
);
- });
-
- it('should track context across updates', () => {
- const SimpleComponent = React.memo(
- class SimpleComponent extends React.Component {
- static contextTypes = {
- foo: PropTypes.string,
- };
-
- state = {
- bar: 'bar',
- };
-
- render() {
- return
{`${this.context.foo}:${this.state.bar}`}
;
- }
- },
- );
-
- const shallowRenderer = createRenderer();
- let result = shallowRenderer.render(
, {
- foo: 'foo',
- });
- expect(result).toEqual(
foo:bar
);
-
- const instance = shallowRenderer.getMountedInstance();
- instance.setState({bar: 'baz'});
-
- result = shallowRenderer.getRenderOutput();
- expect(result).toEqual(
foo:baz
);
- });
-
- it('should filter context by contextTypes', () => {
- const SimpleComponent = React.memo(
- class SimpleComponent extends React.Component {
- static contextTypes = {
- foo: PropTypes.string,
- };
- render() {
- return
{`${this.context.foo}:${this.context.bar}`}
;
- }
- },
- );
-
- const shallowRenderer = createRenderer();
- const result = shallowRenderer.render(
, {
- foo: 'foo',
- bar: 'bar',
- });
- expect(result).toEqual(
foo:undefined
);
- });
-
- it('can fail context when shallowly rendering', () => {
- const SimpleComponent = React.memo(
- class SimpleComponent extends React.Component {
- static contextTypes = {
- name: PropTypes.string.isRequired,
- };
-
- render() {
- return
{this.context.name}
;
- }
- },
- );
-
- const shallowRenderer = createRenderer();
- expect(() => shallowRenderer.render(
)).toErrorDev(
- 'Warning: Failed context type: The context `name` is marked as ' +
- 'required in `SimpleComponent`, but its value is `undefined`.\n' +
- ' in SimpleComponent (at **)',
- );
- });
-
- it('should warn about propTypes (but only once)', () => {
- const SimpleComponent = React.memo(
- class SimpleComponent extends React.Component {
- static propTypes = {
- name: PropTypes.string.isRequired,
- };
-
- render() {
- return React.createElement('div', null, this.props.name);
- }
- },
- );
-
- const shallowRenderer = createRenderer();
- expect(() =>
- shallowRenderer.render(React.createElement(SimpleComponent, {name: 123})),
- ).toErrorDev(
- 'Warning: Failed prop type: Invalid prop `name` of type `number` ' +
- 'supplied to `SimpleComponent`, expected `string`.\n' +
- ' in SimpleComponent',
- );
- });
-
- it('should enable rendering of cloned element', () => {
- const SimpleComponent = React.memo(
- class SimpleComponent extends React.Component {
- constructor(props) {
- super(props);
-
- this.state = {
- bar: 'bar',
- };
- }
-
- render() {
- return
{`${this.props.foo}:${this.state.bar}`}
;
- }
- },
- );
-
- const shallowRenderer = createRenderer();
- const el =
;
- let result = shallowRenderer.render(el);
- expect(result).toEqual(
foo:bar
);
-
- const cloned = React.cloneElement(el, {foo: 'baz'});
- result = shallowRenderer.render(cloned);
- expect(result).toEqual(
baz:bar
);
- });
-
- it('this.state should be updated on setState callback inside componentWillMount', () => {
- let stateSuccessfullyUpdated = false;
-
- const Component = React.memo(
- class Component extends React.Component {
- constructor(props, context) {
- super(props, context);
- this.state = {
- hasUpdatedState: false,
- };
- }
-
- UNSAFE_componentWillMount() {
- this.setState(
- {hasUpdatedState: true},
- () => (stateSuccessfullyUpdated = this.state.hasUpdatedState),
- );
- }
-
- render() {
- return
{this.props.children}
;
- }
- },
- );
-
- const shallowRenderer = createRenderer();
- shallowRenderer.render(
);
- expect(stateSuccessfullyUpdated).toBe(true);
- });
-
- it('should handle multiple callbacks', () => {
- const mockFn = jest.fn();
- const shallowRenderer = createRenderer();
-
- const Component = React.memo(
- class Component extends React.Component {
- constructor(props, context) {
- super(props, context);
- this.state = {
- foo: 'foo',
- };
- }
-
- UNSAFE_componentWillMount() {
- this.setState({foo: 'bar'}, () => mockFn());
- this.setState({foo: 'foobar'}, () => mockFn());
- }
-
- render() {
- return
{this.state.foo}
;
- }
- },
- );
-
- shallowRenderer.render(
);
-
- expect(mockFn).toHaveBeenCalledTimes(2);
-
- // Ensure the callback queue is cleared after the callbacks are invoked
- const mountedInstance = shallowRenderer.getMountedInstance();
- mountedInstance.setState({foo: 'bar'}, () => mockFn());
- expect(mockFn).toHaveBeenCalledTimes(3);
- });
-
- it('should call the setState callback even if shouldComponentUpdate = false', done => {
- const mockFn = jest.fn().mockReturnValue(false);
-
- const Component = React.memo(
- class Component extends React.Component {
- constructor(props, context) {
- super(props, context);
- this.state = {
- hasUpdatedState: false,
- };
- }
-
- shouldComponentUpdate() {
- return mockFn();
- }
-
- render() {
- return
{this.state.hasUpdatedState}
;
- }
- },
- );
-
- const shallowRenderer = createRenderer();
- shallowRenderer.render(
);
-
- const mountedInstance = shallowRenderer.getMountedInstance();
- mountedInstance.setState({hasUpdatedState: true}, () => {
- expect(mockFn).toBeCalled();
- expect(mountedInstance.state.hasUpdatedState).toBe(true);
- done();
- });
- });
-
- it('throws usefully when rendering badly-typed elements', () => {
- const shallowRenderer = createRenderer();
-
- const renderAndVerifyWarningAndError = (Component, typeString) => {
- expect(() => {
- expect(() => shallowRenderer.render(
)).toErrorDev(
- 'React.createElement: type is invalid -- expected a string ' +
- '(for built-in components) or a class/function (for composite components) ' +
- `but got: ${typeString}.`,
- );
- }).toThrowError(
- 'ReactShallowRenderer render(): Shallow rendering works only with custom ' +
- `components, but the provided element type was \`${typeString}\`.`,
- );
- };
-
- renderAndVerifyWarningAndError(undefined, 'undefined');
- renderAndVerifyWarningAndError(null, 'null');
- renderAndVerifyWarningAndError([], 'array');
- renderAndVerifyWarningAndError({}, 'object');
- });
-
- it('should have initial state of null if not defined', () => {
- const SomeComponent = React.memo(
- class SomeComponent extends React.Component {
- render() {
- return
;
- }
- },
- );
-
- const shallowRenderer = createRenderer();
- shallowRenderer.render(
);
-
- expect(shallowRenderer.getMountedInstance().state).toBeNull();
- });
-
- it('should invoke both deprecated and new lifecycles if both are present', () => {
- const log = [];
-
- const Component = React.memo(
- class Component extends React.Component {
- componentWillMount() {
- log.push('componentWillMount');
- }
- componentWillReceiveProps() {
- log.push('componentWillReceiveProps');
- }
- componentWillUpdate() {
- log.push('componentWillUpdate');
- }
- UNSAFE_componentWillMount() {
- log.push('UNSAFE_componentWillMount');
- }
- UNSAFE_componentWillReceiveProps() {
- log.push('UNSAFE_componentWillReceiveProps');
- }
- UNSAFE_componentWillUpdate() {
- log.push('UNSAFE_componentWillUpdate');
- }
- render() {
- return null;
- }
- },
- );
-
- const shallowRenderer = createRenderer();
- shallowRenderer.render(
);
- expect(log).toEqual(['componentWillMount', 'UNSAFE_componentWillMount']);
-
- log.length = 0;
-
- shallowRenderer.render(
);
- expect(log).toEqual([
- 'componentWillReceiveProps',
- 'UNSAFE_componentWillReceiveProps',
- 'componentWillUpdate',
- 'UNSAFE_componentWillUpdate',
- ]);
- });
-
- it('should stop the update when setState returns null or undefined', () => {
- const log = [];
- let instance;
- const Component = React.memo(
- class Component extends React.Component {
- constructor(props) {
- super(props);
- this.state = {
- count: 0,
- };
- }
- render() {
- log.push('render');
- instance = this;
- return null;
- }
- },
- );
- const shallowRenderer = createRenderer();
- shallowRenderer.render(
);
- log.length = 0;
- instance.setState(() => null);
- instance.setState(() => undefined);
- instance.setState(null);
- instance.setState(undefined);
- expect(log).toEqual([]);
- instance.setState(state => ({count: state.count + 1}));
- expect(log).toEqual(['render']);
- });
-
- it('should not get this in a function component', () => {
- const logs = [];
- const Foo = React.memo(function Foo() {
- logs.push(this);
- return
foo
;
- });
- const shallowRenderer = createRenderer();
- shallowRenderer.render(
);
- expect(logs).toEqual([undefined]);
- });
-});
diff --git a/packages/react-transport-dom-relay/package.json b/packages/react-transport-dom-relay/package.json
index 77cbf1284ca54..fbb3e0622e522 100644
--- a/packages/react-transport-dom-relay/package.json
+++ b/packages/react-transport-dom-relay/package.json
@@ -12,7 +12,7 @@
"scheduler": "^0.11.0"
},
"peerDependencies": {
- "react": "^16.0.0",
- "react-dom": "^16.0.0"
+ "react": "^17.0.0-alpha",
+ "react-dom": "^17.0.0-alpha"
}
}
diff --git a/packages/react-transport-dom-webpack/package.json b/packages/react-transport-dom-webpack/package.json
index 4dd0be987710c..b15fbdd356e9c 100644
--- a/packages/react-transport-dom-webpack/package.json
+++ b/packages/react-transport-dom-webpack/package.json
@@ -34,8 +34,8 @@
"node": ">=0.10.0"
},
"peerDependencies": {
- "react": "^16.0.0",
- "react-dom": "^16.0.0",
+ "react": "^17.0.0-alpha",
+ "react-dom": "^17.0.0-alpha",
"webpack": "^4.43.0"
},
"dependencies": {
diff --git a/packages/react/package.json b/packages/react/package.json
index 29d293bf231ee..26ee45210b78e 100644
--- a/packages/react/package.json
+++ b/packages/react/package.json
@@ -4,7 +4,7 @@
"keywords": [
"react"
],
- "version": "16.13.1",
+ "version": "17.0.0-alpha.0",
"homepage": "https://reactjs.org/",
"bugs": "https://github.com/facebook/react/issues",
"license": "MIT",
diff --git a/packages/shared/ReactVersion.js b/packages/shared/ReactVersion.js
index a44b7ad43e913..a45f8bf18f4e5 100644
--- a/packages/shared/ReactVersion.js
+++ b/packages/shared/ReactVersion.js
@@ -6,4 +6,4 @@
*/
// TODO: this is special because it gets imported during build.
-export default '16.13.1';
+export default '17.0.0-alpha.0';
diff --git a/packages/use-subscription/package.json b/packages/use-subscription/package.json
index ab1fc13f27c3d..42c0e4913f9fa 100644
--- a/packages/use-subscription/package.json
+++ b/packages/use-subscription/package.json
@@ -19,7 +19,7 @@
"object-assign": "^4.1.1"
},
"peerDependencies": {
- "react": "^16.8.0"
+ "react": "^17.0.0-alpha"
},
"devDependencies": {
"rxjs": "^5.5.6"
diff --git a/scripts/rollup/bundles.js b/scripts/rollup/bundles.js
index 83117e70dedc4..f8de9880b7e40 100644
--- a/scripts/rollup/bundles.js
+++ b/scripts/rollup/bundles.js
@@ -428,19 +428,6 @@ const bundles = [
]),
}),
},
- {
- bundleTypes: [UMD_DEV, UMD_PROD],
- moduleType: NON_FIBER_RENDERER,
- entry: 'react-test-renderer/shallow',
- global: 'ReactShallowRenderer',
- externals: ['react', 'scheduler', 'scheduler/unstable_mock'],
- babel: opts =>
- Object.assign({}, opts, {
- plugins: opts.plugins.concat([
- [require.resolve('@babel/plugin-transform-classes'), {loose: true}],
- ]),
- }),
- },
/******* React Noop Renderer (used for tests) *******/
{
diff --git a/scripts/rollup/forks.js b/scripts/rollup/forks.js
index 80f1b724aa6dd..5f4e1480a9ee0 100644
--- a/scripts/rollup/forks.js
+++ b/scripts/rollup/forks.js
@@ -56,11 +56,6 @@ const forks = Object.freeze({
return 'shared/forks/object-assign.umd.js';
},
- 'react-shallow-renderer': () => {
- // Use ESM build of `react-shallow-renderer`.
- return 'react-shallow-renderer/esm/index.js';
- },
-
// Without this fork, importing `shared/ReactSharedInternals` inside
// the `react` package itself would not work due to a cyclical dependency.
'shared/ReactSharedInternals': (bundleType, entry, dependencies) => {