Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ensure that component prop 'context' really contains a React context … #1134

Merged
merged 10 commits into from Jan 8, 2019
9 changes: 6 additions & 3 deletions rollup.config.js
Expand Up @@ -2,7 +2,7 @@ import nodeResolve from 'rollup-plugin-node-resolve'
import babel from 'rollup-plugin-babel'
import replace from 'rollup-plugin-replace'
import commonjs from 'rollup-plugin-commonjs'
import {uglify} from 'rollup-plugin-uglify'
import { uglify } from 'rollup-plugin-uglify'
import pkg from './package.json'

const env = process.env.NODE_ENV
Expand All @@ -22,14 +22,17 @@ const config = {
nodeResolve(),
babel({
exclude: '**/node_modules/**',
runtimeHelpers: true,
runtimeHelpers: true
}),
replace({
'process.env.NODE_ENV': JSON.stringify(env)
}),
commonjs({
namedExports: {
'node_modules/react-is/index.js': ['isValidElementType'],
'node_modules/react-is/index.js': [
'isValidElementType',
'isContextConsumer'
]
}
})
]
Expand Down
9 changes: 7 additions & 2 deletions src/components/connectAdvanced.js
@@ -1,7 +1,7 @@
import hoistStatics from 'hoist-non-react-statics'
import invariant from 'invariant'
import React, { Component, PureComponent } from 'react'
import { isValidElementType } from 'react-is'
import { isValidElementType, isContextConsumer } from 'react-is'

import { ReactReduxContext } from './Context'

Expand Down Expand Up @@ -213,7 +213,12 @@ export default function connectAdvanced(
}

render() {
const ContextToUse = this.props.context || Context
const ContextToUse =
this.props.context &&
this.props.context.Consumer &&
isContextConsumer(<this.props.context.Consumer />)
? this.props.context
: Context

return (
<ContextToUse.Consumer>
Expand Down
30 changes: 30 additions & 0 deletions test/components/connect.spec.js
Expand Up @@ -1564,6 +1564,36 @@ describe('React', () => {
expect(actualState).toEqual(expectedState)
})

it('should ignore non-react-context values that are passed as a prop to the component', () => {
class Container extends Component {
render() {
return <Passthrough />
}
}

const nonContext = { someProperty: {} }

let actualState

const expectedState = { foos: {} }

const decorator = connect(state => {
actualState = state
return {}
})
const Decorated = decorator(Container)

const store = createStore(() => expectedState)

rtl.render(
<ProviderMock store={store}>
<Decorated context={nonContext} />
</ProviderMock>
)

expect(actualState).toEqual(expectedState)
})

it('should throw an error if the store is not in the props or context', () => {
const spy = jest.spyOn(console, 'error').mockImplementation(() => {})

Expand Down