From 2c8fa0c59b47c09097df7876b31eae88a3457e6a Mon Sep 17 00:00:00 2001 From: Stefan <5585744+casdevs@users.noreply.github.com> Date: Mon, 17 Dec 2018 10:52:33 +0100 Subject: [PATCH 1/9] Ensure that component prop 'context' really contains a React context before using it after switching to react-redux 6.0.0, we've had a lot of errors stating Warning: React.createElement: type is invalid -- expected a string (for built-in components) or a class/function (for composite components) but got: undefined. You likely forgot to export your component from the file it's defined in, or you might have mixed up default and named imports. all over in our app. After digging deeper, we've discovered that we use a lot of (connected) components using a property named 'context' which conflicts with your new connectAdvanced code. So maybe you can improve the check on this.props.context a little bit to ensure it is used only if it really contains a valid React context. --- src/components/connectAdvanced.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/connectAdvanced.js b/src/components/connectAdvanced.js index 4dbb9ff1a..607094257 100644 --- a/src/components/connectAdvanced.js +++ b/src/components/connectAdvanced.js @@ -213,7 +213,7 @@ export default function connectAdvanced( } render() { - const ContextToUse = this.props.context || Context + const ContextToUse = (this.props.context && this.props.context.Consumer) ? this.props.context : Context return ( From 0d79a85d070963374ba56b4c8a05eed1264a42a6 Mon Sep 17 00:00:00 2001 From: Stefan <5585744+casdevs@users.noreply.github.com> Date: Mon, 17 Dec 2018 11:00:26 +0100 Subject: [PATCH 2/9] Update connectAdvanced.js --- src/components/connectAdvanced.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/connectAdvanced.js b/src/components/connectAdvanced.js index 607094257..958bc2226 100644 --- a/src/components/connectAdvanced.js +++ b/src/components/connectAdvanced.js @@ -213,7 +213,7 @@ export default function connectAdvanced( } render() { - const ContextToUse = (this.props.context && this.props.context.Consumer) ? this.props.context : Context + const ContextToUse = this.props.context && this.props.context.Consumer ? this.props.context : Context return ( From c046ae61cce5d45530d270bc43ce464897127985 Mon Sep 17 00:00:00 2001 From: Stefan <5585744+casdevs@users.noreply.github.com> Date: Mon, 17 Dec 2018 11:05:49 +0100 Subject: [PATCH 3/9] Update connectAdvanced.js --- src/components/connectAdvanced.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/components/connectAdvanced.js b/src/components/connectAdvanced.js index 958bc2226..9081f1755 100644 --- a/src/components/connectAdvanced.js +++ b/src/components/connectAdvanced.js @@ -213,7 +213,9 @@ export default function connectAdvanced( } render() { - const ContextToUse = this.props.context && this.props.context.Consumer ? this.props.context : Context + const ContextToUse = this.props.context && this.props.context.Consumer + ? this.props.context + : Context return ( From 9f1eddec7171bc44b464ce9fb0cb9a3a70703b04 Mon Sep 17 00:00:00 2001 From: "stefan.hausmann" Date: Mon, 17 Dec 2018 20:38:30 +0100 Subject: [PATCH 4/9] improved check whether context given as a prop is a real ReactContext --- src/components/connectAdvanced.js | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/components/connectAdvanced.js b/src/components/connectAdvanced.js index 9081f1755..bf42d54f0 100644 --- a/src/components/connectAdvanced.js +++ b/src/components/connectAdvanced.js @@ -213,9 +213,12 @@ export default function connectAdvanced( } render() { - const ContextToUse = this.props.context && this.props.context.Consumer - ? this.props.context - : Context + const ContextToUse = + this.props.context && + this.props.context.Provider && + this.props.context.Consumer + ? this.props.context + : Context return ( From 5befe046143dcc65a4286c782d989805bc9c01de Mon Sep 17 00:00:00 2001 From: "stefan.hausmann" Date: Mon, 17 Dec 2018 20:39:11 +0100 Subject: [PATCH 5/9] added test for ignoring non-react-context values passed as a prop to the component --- test/components/connect.spec.js | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/test/components/connect.spec.js b/test/components/connect.spec.js index 7a8629ec2..4ca9a2fd9 100644 --- a/test/components/connect.spec.js +++ b/test/components/connect.spec.js @@ -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 + } + } + + 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( + + + + ) + + 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(() => {}) From f4262b82d4455d9cd343d6557472632a4b75769a Mon Sep 17 00:00:00 2001 From: Tim Dorr Date: Mon, 17 Dec 2018 15:26:45 -0500 Subject: [PATCH 6/9] Use react-is checks --- src/components/connectAdvanced.js | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/components/connectAdvanced.js b/src/components/connectAdvanced.js index bf42d54f0..30ef96237 100644 --- a/src/components/connectAdvanced.js +++ b/src/components/connectAdvanced.js @@ -1,7 +1,11 @@ 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, + isContextProvider +} from 'react-is' import { ReactReduxContext } from './Context' @@ -215,8 +219,8 @@ export default function connectAdvanced( render() { const ContextToUse = this.props.context && - this.props.context.Provider && - this.props.context.Consumer + isContextProvider(this.props.context.Provider) && + isContextConsumer(this.props.context.Consumer) ? this.props.context : Context From 6f72646156d39419b33363e4cca8c950b774d98f Mon Sep 17 00:00:00 2001 From: Tim Dorr Date: Mon, 17 Dec 2018 15:38:35 -0500 Subject: [PATCH 7/9] Just check Consumer. Good enough! --- src/components/connectAdvanced.js | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/src/components/connectAdvanced.js b/src/components/connectAdvanced.js index 30ef96237..676de22e5 100644 --- a/src/components/connectAdvanced.js +++ b/src/components/connectAdvanced.js @@ -1,11 +1,7 @@ import hoistStatics from 'hoist-non-react-statics' import invariant from 'invariant' import React, { Component, PureComponent } from 'react' -import { - isValidElementType, - isContextConsumer, - isContextProvider -} from 'react-is' +import { isValidElementType, isContextConsumer } from 'react-is' import { ReactReduxContext } from './Context' @@ -219,7 +215,6 @@ export default function connectAdvanced( render() { const ContextToUse = this.props.context && - isContextProvider(this.props.context.Provider) && isContextConsumer(this.props.context.Consumer) ? this.props.context : Context From 59ff826bd3998c1b1e7d3688a1e0afe751e7a42b Mon Sep 17 00:00:00 2001 From: "stefan.hausmann" Date: Tue, 8 Jan 2019 18:45:25 +0100 Subject: [PATCH 8/9] improved check for context.Consumer --- src/components/connectAdvanced.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/components/connectAdvanced.js b/src/components/connectAdvanced.js index bf42d54f0..cd9795ab4 100644 --- a/src/components/connectAdvanced.js +++ b/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' @@ -215,8 +215,8 @@ export default function connectAdvanced( render() { const ContextToUse = this.props.context && - this.props.context.Provider && - this.props.context.Consumer + this.props.context.Consumer && + isContextConsumer() ? this.props.context : Context From 50fd8943318ac16cbabeed02213de4c33ce3c79a Mon Sep 17 00:00:00 2001 From: "stefan.hausmann" Date: Tue, 8 Jan 2019 19:02:54 +0100 Subject: [PATCH 9/9] added missing export 'isContextConsumer' in rollup config --- rollup.config.js | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/rollup.config.js b/rollup.config.js index ae0c7264a..9a72d4eb2 100644 --- a/rollup.config.js +++ b/rollup.config.js @@ -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 @@ -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' + ] } }) ]