diff --git a/src/components/connectAdvanced.js b/src/components/connectAdvanced.js
index 6736e7a9d..7ad013f23 100644
--- a/src/components/connectAdvanced.js
+++ b/src/components/connectAdvanced.js
@@ -106,6 +106,10 @@ export default function connectAdvanced(
`or explicitly pass "${storeKey}" as a prop to "${displayName}".`
)
+ // make sure `getState` is properly bound in order to avoid breaking
+ // custom store implementations that rely on the store's context
+ this.getState = this.store.getState.bind(this.store);
+
this.initSelector()
this.initSubscription()
}
@@ -159,7 +163,8 @@ export default function connectAdvanced(
}
initSelector() {
- const { dispatch, getState } = this.store
+ const { dispatch } = this.store
+ const { getState } = this;
const sourceSelector = selectorFactory(dispatch, selectorFactoryOptions)
// wrap the selector in an object that tracks its results between runs
diff --git a/src/utils/Subscription.js b/src/utils/Subscription.js
index b26615ed2..b3b63ec4d 100644
--- a/src/utils/Subscription.js
+++ b/src/utils/Subscription.js
@@ -5,7 +5,7 @@ export default class Subscription {
constructor(store, parentSub) {
this.subscribe = parentSub
? parentSub.addNestedSub.bind(parentSub)
- : store.subscribe
+ : store.subscribe.bind(store)
this.unsubscribe = null
this.nextListeners = this.currentListeners = []
diff --git a/test/components/connect.spec.js b/test/components/connect.spec.js
index eadd2e927..b7f8e2a16 100644
--- a/test/components/connect.spec.js
+++ b/test/components/connect.spec.js
@@ -25,6 +25,30 @@ describe('React', () => {
}
}
+ class ContextBoundStore {
+ constructor(reducer) {
+ this.reducer = reducer
+ this.listeners = []
+ this.state = undefined
+ this.dispatch({})
+ }
+
+ getState() {
+ return this.state
+ }
+
+ subscribe(listener) {
+ this.listeners.push(listener)
+ return (() => this.listeners.filter(l => l !== listener))
+ }
+
+ dispatch(action) {
+ this.state = this.reducer(this.getState(), action)
+ this.listeners.forEach(l => l())
+ return action
+ }
+ }
+
ProviderMock.childContextTypes = {
store: PropTypes.object.isRequired
}
@@ -134,6 +158,30 @@ describe('React', () => {
expect(stub.props.string).toBe('ab')
})
+ it('should retain the store\'s context', () => {
+ const store = new ContextBoundStore(stringBuilder)
+
+ let Container = connect(
+ state => ({ string: state })
+ )(function Container(props) {
+ return
+ })
+
+ const spy = expect.spyOn(console, 'error')
+ const tree = TestUtils.renderIntoDocument(
+
+
+
+ )
+ spy.destroy()
+ expect(spy.calls.length).toBe(0)
+
+ const stub = TestUtils.findRenderedComponentWithType(tree, Passthrough)
+ expect(stub.props.string).toBe('')
+ store.dispatch({ type: 'APPEND', body: 'a' })
+ expect(stub.props.string).toBe('a')
+ })
+
it('should handle dispatches before componentDidMount', () => {
const store = createStore(stringBuilder)