-
Notifications
You must be signed in to change notification settings - Fork 4k
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
feat(ElementType): new wrapper for all elements #2306
Conversation
5633ae5
to
d9f1353
Compare
} from '../../lib' | ||
|
||
/** | ||
* A container limits content to a maximum width. | ||
*/ | ||
function Container(props) { | ||
const InnerContainer = (props) => { |
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.
- As
Container
is wrapped with HOC, we can't userprototype.name
. So, we can use arrow functions for components _meta
should be exported on the default export, now it's an enhanced component. However, I'm not happy aboutInner-
prefix
if (!_.isNil(dimmer) || !_.isNil(label) || !_.isNil(wrapped) || !childrenUtils.isNil(children)) return 'div' | ||
} | ||
|
||
const Image = withComputedType(computeType)(InnerImage) |
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.
Type computing function moved to HOC
const { children, className, content } = props | ||
const classes = cx('header', className) | ||
const rest = getUnhandledProps(ListHeader, props) | ||
const ElementType = getElementType(ListHeader, props) | ||
const rest = getUnhandledProps(InnerListHeader, props, { passAs: true }) |
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.
Another nasty thing. as
should be passed to ElementType
, but not all our components are updated.
I've already add ignoreProps
option babel-plugin-transform-react-handled-props
plugin, but we can't enable it until we will update all components
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.
@layershifter do we have a list of the components that still need to get updated somewhere? I am assuming this exists in another conversation/PR somewhere.
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.
After this PR will be merged I will update #1321 with list for update. I don't want to do this in single PR because there will be too many changes.
* @returns {{}} A shallow copy of the prop object | ||
*/ | ||
const getUnhandledProps = (Component, props) => { | ||
const getUnhandledProps = (Component, props, options = {}) => { |
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.
This function will be restored after we will update all components.
d9f1353
to
d117cf6
Compare
Codecov Report
@@ Coverage Diff @@
## master #2306 +/- ##
==========================================
+ Coverage 99.74% 99.74% +<.01%
==========================================
Files 160 160
Lines 2751 2767 +16
==========================================
+ Hits 2744 2760 +16
Misses 7 7
Continue to review full report at Codecov.
|
@levithomason I'll be glad to hear your feedback 😄 |
So sorry for the delay, I have not had enough time to fully grok this one. Any input by @davezuko or @brianespinosa would be much help. I don't want to block progress, but we also need to validate this approach across another min or two. |
…/Semantic-Org/Semantic-UI-React into feat/element-type # Conflicts: # src/elements/Image/Image.js # test/specs/elements/Image/Image-test.js
Any update on the status of this? |
I'm worried about the complexity here. My primary concern is this obfuscates the basic definition what a component is and does so for all of our components. Thankfully, it looks like React will now support ref forwarding which may solve this problem for us with Per
I would agree with this sentiment. I want to try some other approaches before merging this. I'd also be open to leaving this unsolved until React >= 16.3 ships (with |
Agreed. Seems to be close (relatively speaking). If ref forwarding will solve our issue it probably makes the most sense to wait for that. |
Hear me out before throwing stones but I'm beginning to consider extending a base component for all our HOC needs. Why?! I think a component library is a unique thing in terms of React components for apps. In an application, you have many types of components with varying needs. Whereas, in a component library, every component needs identical base functionality. We can either bundle this into a single base component that we extend, or, go the functional approach of making several HOCs and wrap every component with every HOC to get the base feature set needed. HOCs are hard to debug, test through, and add a lot to the render tree. Again, in an application, it is typically easier to test dumb components and keep more complex features in a single tested HOC. However, in a component library, it seems ludicrous to have every component be a stack of function calls and component wrappers. Every element in a consumer's app would be a stack of function calls and its own notable render tree. Imagine when they build more complex controls, or, imagine our own controls such as an Input that contains a Button and a Label. Rather than rendering three React components, we'd be rendering n*h components for a single control where n is the number of components and h is the number of HOCs required for our base functionality. A base component would make every component in the library a single flat component. It would also very easily mean all components have all the features they need. I know this is not the direction of the community, but, I'd love to hear thoughts and opinions on this. |
@levithomason I can also see how this simplifies things with Fela styling too. Additionally, my OCD hates the deep render tree. |
I'll try updating a few components to use a base component and see how it goes. |
@levithomason I'm think that we should go with |
OK, I'll wait for you. Are you thinking it will solve this problem?: const StatelessComponent = () => <div />
<Button as={StatelessComponent} />
|
Adding this to #2747 |
Closing in favor of #2844. |
Replaces #1879.
What?
This PR offers the complex multipurpose solution for our internal problems with refs. These changes will allow to improve work with
as
prop and refs.Why so complex?
We cannot simply use
ref
, it' isn't a prop. It has a same behaviour askey
- it never passed to a component. However, there were numerous issues about refs (#1740, #1602, #1849, #1732 and more) and it's time to make something in this way.document.querySelector
is a workaround, but it's not a solution.Problem is a well known in React's world, there is a long-live issue facebook/react#4213, there was also the RFC facebook/react#6974 from Dan.
Variants
componentRef
&innerRef
refs.md
componentRef
connect
HOC,withRef
innerRef
Link.md
Solution
Several months ago☹️ I've started to work on this problem. I made few iterations and checked many solutions. This PR is its result, the solution consists from two components.
withComputedType
This is a HOC that allows to pass an already computed element type in
as
prop. In fact it's the most controversial part of this PR.We need the computed type only in several components (i.e.
Button
,Image
), it also simplifies work with defaultas
values (seeForm
,Image
). I think that we can go with it, as we plan more HOCs in future for transitions and popups.The only valid against that I see is the increase of the render tree, all our components will be wrapped with it.
ElementType
It has the only one task, to decide how to handle
innerRef
s. If we simply wrap it withRef
we will always callfindDOMNode
, even when we actually don't need it.P.S.
I want to ship this PR as start point and apply changes to left components iteratively. After all components will be updated, I will able to cleanup tests.