diff --git a/src/components/LegacyProvider.js b/src/components/LegacyProvider.js new file mode 100644 index 000000000..6a77a0636 --- /dev/null +++ b/src/components/LegacyProvider.js @@ -0,0 +1,29 @@ +import React, { Component } from 'react' +import PropTypes from 'prop-types' + +import Provider from './Provider' + +class LegacyProvider extends Component { + getChildContext() { + return { store: this.props.store } + } + + render() { + const { store, ...props } = this.props + return + } +} + +LegacyProvider.propTypes = { + store: PropTypes.shape({ + subscribe: PropTypes.func.isRequired, + dispatch: PropTypes.func.isRequired, + getState: PropTypes.func.isRequired + }) +} + +LegacyProvider.childContextTypes = { + store: PropTypes.object.isRequired +} + +export default LegacyProvider diff --git a/src/index.js b/src/index.js index 22b1bd9e5..b75f77dcd 100644 --- a/src/index.js +++ b/src/index.js @@ -1,6 +1,7 @@ import Provider from './components/Provider' +import LegacyProvider from './components/LegacyProvider' import connectAdvanced from './components/connectAdvanced' import { ReactReduxContext } from './components/Context' import connect from './connect/connect' -export { Provider, connectAdvanced, ReactReduxContext, connect } +export { Provider, LegacyProvider, connectAdvanced, ReactReduxContext, connect } diff --git a/test/components/LegacyProvider.spec.js b/test/components/LegacyProvider.spec.js new file mode 100644 index 000000000..bea7dcf4f --- /dev/null +++ b/test/components/LegacyProvider.spec.js @@ -0,0 +1,74 @@ +import React, { Component } from 'react' +import PropTypes from 'prop-types' +import * as rtl from 'react-testing-library' +import 'jest-dom/extend-expect' + +import { createStore } from 'redux' +import { LegacyProvider } from '../../src/index.js' +import { ReactReduxContext } from '../../src/components/Context' + +const createExampleTextReducer = () => (state = 'example text') => state + +describe('LegacyProvider', () => { + afterEach(() => rtl.cleanup()) + + it('provides a legacy context', () => { + class LegacyChild extends Component { + render() { + const store = this.context.store + + let text = '' + + if (store) { + text = store.getState().toString() + } + + return
{text}
+ } + } + + LegacyChild.contextTypes = { + store: PropTypes.object.isRequired + } + + const store = createStore(createExampleTextReducer()) + + const spy = jest.spyOn(console, 'error').mockImplementation(() => {}) + const tester = rtl.render( + + + + ) + expect(spy).toHaveBeenCalledTimes(0) + spy.mockRestore() + + expect(tester.getByTestId('store')).toHaveTextContent('example text') + }) + + it('passes through everything to the new Provider and provides the new Context as well', () => { + class Child extends Component { + render() { + return ( + + {({ storeState }) => { + return
{storeState}
+ }} +
+ ) + } + } + + const store = createStore(createExampleTextReducer()) + + const spy = jest.spyOn(console, 'error').mockImplementation(() => {}) + const tester = rtl.render( + + + + ) + expect(spy).toHaveBeenCalledTimes(0) + spy.mockRestore() + + expect(tester.getByTestId('store')).toHaveTextContent('example text') + }) +})