diff --git a/src/components/connect.tsx b/src/components/connect.tsx index e5c19499d..19116df41 100644 --- a/src/components/connect.tsx +++ b/src/components/connect.tsx @@ -28,6 +28,7 @@ import { mergePropsFactory } from '../connect/mergeProps' import { createSubscription, Subscription } from '../utils/Subscription' import { useIsomorphicLayoutEffect } from '../utils/useIsomorphicLayoutEffect' import shallowEqual from '../utils/shallowEqual' +import warning from '../utils/warning' import { ReactReduxContext, @@ -405,6 +406,8 @@ export interface Connect { // tslint:enable:no-unnecessary-generics } +let hasWarnedAboutDeprecatedPureOption = false + /** * Connects a React component to a Redux store. * @@ -452,8 +455,9 @@ function connect< }: ConnectOptions = {} ): unknown { if (process.env.NODE_ENV !== 'production') { - if (pure !== undefined) { - throw new Error( + if (pure !== undefined && !hasWarnedAboutDeprecatedPureOption) { + hasWarnedAboutDeprecatedPureOption = true + warning( 'The `pure` option has been removed. `connect` is now always a "pure/memoized" component' ) } diff --git a/test/components/connect.spec.tsx b/test/components/connect.spec.tsx index 1007b03ad..310895509 100644 --- a/test/components/connect.spec.tsx +++ b/test/components/connect.spec.tsx @@ -2912,6 +2912,57 @@ describe('React', () => { expect.stringContaining('was not wrapped in act') ) } + + spy.mockRestore() + }) + + it('should warn one-time-only that `pure` options has been removed', () => { + const spy = jest.spyOn(console, 'error').mockImplementation(() => {}) + const store: Store = createStore(stringBuilder) + + class ContainerA extends Component { + render() { + return + } + } + + const ConnectedContainerA = connect( + (state) => ({ string: state }), + () => ({}), + () => ({}), + // The `pure` option has been removed + // @ts-ignore + { pure: true } + )(ContainerA) + + class ContainerB extends Component { + render() { + return + } + } + + const ConnectedContainerB = connect( + (state) => ({ string: state }), + () => ({}), + () => ({}), + // The `pure` option has been removed + // @ts-ignore + { pure: true } + )(ContainerB) + + rtl.render( + + + + + ) + + expect(spy).toHaveBeenCalledTimes(1) + expect(spy).toHaveBeenCalledWith( + 'The `pure` option has been removed. `connect` is now always a "pure/memoized" component' + ) + + spy.mockRestore() }) }) @@ -3236,9 +3287,13 @@ describe('React', () => { ) - store.dispatch({ type: '' }) - store.dispatch({ type: '' }) - outerComponent.current!.setState(({ count }) => ({ count: count + 1 })) + rtl.act(() => { + store.dispatch({ type: '' }) + store.dispatch({ type: '' }) + outerComponent.current!.setState(({ count }) => ({ + count: count + 1, + })) + }) expect(reduxCountPassedToMapState).toEqual(3) })