This repository has been archived by the owner on Dec 31, 2020. It is now read-only.
-
-
Notifications
You must be signed in to change notification settings - Fork 348
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Browse files
Browse the repository at this point in the history
This change forward writes (but not reads!) of `propTypes` and `defaultProps` on an inject based HoC to the wrapped component, so that propTypes and defaultProps can be defined in a straight forward way.
- Loading branch information
1 parent
7243a9d
commit 666577b
Showing
4 changed files
with
116 additions
and
53 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -7,4 +7,5 @@ custom.js | |
custom.d.ts | ||
index.js | ||
index.d.ts | ||
index.min.js | ||
index.min.js | ||
.vscode |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
666577b
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@jtraub @andykog @Strate would you mind reviewing this proposed solution to #120, #142? See the changelog above. The main idea is: forward assignments to
propTypes
anddefaultProps
from a MobXInjector to the original wrapped components, so that the following is valid:This makes decorating a component with inject more transparent, but reading
propTypes
would always return nothing, which might be weird? Maybe we can detect it is being read as part of Reacts propType validation and then return nothing, otherwise the propTypes of the wrapped component instead?666577b
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@mweststrate, I wouldn't implement such proxying at all.
It's really weird that propTypes becomes
null
. Sometimes people do things like:But I think, the only way to detect that we are inside rendering is to use react's private stuff, right?
666577b
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
666577b
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No that I think of it, not sure why we warn for these static assignments in the first place, actually they are correct? In principle it doesn't matter whether the propTypes are validated on the Injector component or wrapped component. The primary concern of validating propTypes should be to validate external calls of your component, not to validate whether the proper stores are inject / the stores mapper produces the correct result. The same holds for
defaultProps
I guess.@jtraub what was the original reason for implementing #88 ?
666577b
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@jtraub @andykog see: 7f4d5fd
666577b
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@mweststrate, well, 99.9% of time defining propTypes on HOC is not what you want. Can you think of the case where it's needed?
666577b
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@mweststrate, ok, maybe someone can really want to declare propTypes that are not injected with
inject
as a HOC.propTypes just to seperate them and make more obvious, what needs to be passed from parent component (not an options for me as I use eslint proptypes validation)666577b
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the tricky part is that people might often not recognize it as being HoC, or don't give much thought about a HoC is happening:
const A = observer(props => rendering)
-> no hoc,A.propTypes = ..
is okconst A = observer(["store"], props => rendering)
-> hoc,A.propTypes = ..
is not ok ?! But proptypes should be the same, except for"store"
const A = inject("store", observer(props => rendering))
-> hoc,A.propTypes = ..
is not ok ?! But proptypes should be the same, except for"store"
If I remember correct (should test that, actually the following is different:
If I remember correctly (should investigate), 1 and 2 will define
propTypes
on the inner component, whereas 3 and 4 will define it on the HoC. Which style of component declaration people use might depend much on the ES2015 language features they use / like666577b
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Note that in the following scenario the difference is only notable for the store property, not the 'normal'
bold
properties, which need to be passed to HoC anyway, just as to the original component:666577b
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@mweststrate, that inconsistency is really nasty. But I guess, trying to hide the fact that the HOC is used is a bad choice.
It will define propTypes on inner component if you place
transform-decorators-legacy
aftertransform-class-properties
, in your config. Not sure about non-legacy decorators spec666577b
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Well it is not a deliberate choice, it is just that most people will consider the HoC (if there is one) in their mind as "the
XyzComponent
", because from the outside, a HO wrapped component looks just the same as a component. It's called the same etc, butpropTypes
anddefaultProps
suddenly need to be configured on a different place. I think it is partially unavoidable confusion related to HoC's.666577b
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@mweststrate, promoting people to think HoC's is their original component is harmful, HoC is nothing to do with the original component. Here is an example when this abstraction leaks: https://jsfiddle.net/Sl1v3r/qqase12u/
Maybe, the amount on confusion could be lower if we deprecate
observer([injectedProps], component)
, so thatobserver
always only makes component observable,inject
always returns HoC?I would also give HoC's different name, something like
${originalName}Injector
666577b
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@andykog Ok, I think you convinced me :). I think
observer(["store"])
should probably indeed be deprecated in v4, it only adds to the confusion.Nonetheless, giving a warning when assigning PropTypes to the HoC might still be too aggressive? Basically it is not bad to assign propTypes to the HoC? The name is already improved btw :)
For the name, this will be part of v4 as well:
666577b
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I really don't know, as I said, I believe most of the time assigning propTypes on HoC is not what user intended, but I can imagine such usecase (seperating general propTypes from injected).
I thought about alternative, but its a bit to tricky: we could intercept propTypes, declared on HoC and wrap all the validators in additional function like this:
666577b
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@mweststrate
Initially, I wanted to have transparent passing of
propTypes
anddefaultProps
(see #70 (comment))But then you've implemented
wrappedComponent
property so I needed a way of preventing me fromMyComponent.propTypes = { ..