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

Conversation

casdevs
Copy link
Contributor

@casdevs casdevs commented Dec 17, 2018

…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 already 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.

…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.
@netlify
Copy link

netlify bot commented Dec 17, 2018

Deploy preview for react-redux-docs ready!

Built with commit 50fd894

https://deploy-preview-1134--react-redux-docs.netlify.com

@timdorr
Copy link
Member

timdorr commented Dec 17, 2018

Can you add a test? And please run you code through Prettier.

@casdevs
Copy link
Contributor Author

casdevs commented Dec 17, 2018

ok, I'm going to add tests within the next few days

@casdevs
Copy link
Contributor Author

casdevs commented Dec 17, 2018

improved checks & added test

@casdevs
Copy link
Contributor Author

casdevs commented Dec 17, 2018

maybe it would even be better to check for this.props.context.$$typeof === REACT_CONTEXT_TYPE, but react doesn't seem to export its type symbols...

@markerikson
Copy link
Contributor

We do have react-is being imported already - might be a function in there you can use?

@casdevs
Copy link
Contributor Author

casdevs commented Dec 17, 2018

we could check for this.props.context.$$typeof === ContextConsumer
with export const ContextConsumer = REACT_CONTEXT_TYPE; being exported by 'react-is'
this works and all tests would succeed.

But a dedicated method like isContext doesn't seem to be available from 'react-is'.

@timdorr
Copy link
Member

timdorr commented Dec 17, 2018

react-is has specific functions for those checks:

ReactIs.isContextConsumer(<ThemeContext.Consumer />); // true
ReactIs.isContextProvider(<ThemeContext.Provider />); // true

@timdorr
Copy link
Member

timdorr commented Dec 17, 2018

Added that for you now.

@casdevs
Copy link
Contributor Author

casdevs commented Dec 17, 2018

great, thanks!
When we decide to have type checks on members of this.props.context, we could even omit the check on this.props.context.provider as only .consumer is used after the checks.

@timdorr
Copy link
Member

timdorr commented Dec 17, 2018

Yeah, I removed that. It was also complaining about isContextProvider not being exported from react-is. Weird.

@casdevs
Copy link
Contributor Author

casdevs commented Dec 17, 2018

hm, it doesn't seem to know isContextConsumer either...!?

@timdorr
Copy link
Member

timdorr commented Dec 17, 2018

And now isContextConsumer. wut?

@casdevs
Copy link
Contributor Author

casdevs commented Dec 17, 2018

weird, when running the tests locally, isContextConsumer is imported correctly.

however, the check must be done this way, otherwise other test cases fail:
const ContextToUse = this.props.context && this.props.context.Consumer && isContextConsumer(<this.props.context.Consumer />) ? this.props.context : Context

seems to be overhead, so maybe it would be better to simply check for
this.props.context.$$typeof === ContextConsumer as I've stated above.
I'm beginning to think that react-is' ContextConsumer export should rather be named ContextToBeConsumedByContextConsumer though....

@casdevs
Copy link
Contributor Author

casdevs commented Jan 8, 2019

Happy new year to all of you!
I've updated the code again and the pull request should now be ok to get merged in.

@timdorr
Copy link
Member

timdorr commented Jan 8, 2019

Ah, I missed the Rollup config! I knew it was something obvious.

@timdorr
Copy link
Member

timdorr commented Jan 8, 2019

OK, this looks good to me. Thanks!

@timdorr timdorr merged commit 5199d9d into reduxjs:master Jan 8, 2019
@casdevs
Copy link
Contributor Author

casdevs commented Jan 8, 2019

great, thanks for merging that in!

@maxkostow
Copy link

When do you plan on cutting a new release with this change?

@markerikson
Copy link
Contributor

@timdorr ?

webguru7 pushed a commit to webguru7/react-redux that referenced this pull request Dec 8, 2022
reduxjs#1134)

* 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.

* Update connectAdvanced.js

* Update connectAdvanced.js

* improved check whether context given as a prop is a real ReactContext

* added test for ignoring non-react-context values passed as a prop to the component

* Use react-is checks

* Just check Consumer. Good enough!

* improved check for context.Consumer

* added missing export 'isContextConsumer' in rollup config
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants