-
Notifications
You must be signed in to change notification settings - Fork 1
Some optimisations on the component #7
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
base: master
Are you sure you want to change the base?
Conversation
- Add prop to keep the child when closed. - Use onTransitionEnd instead of setTimeout. - Forward remaining props on root element
- @emotion-core is not required as peer dependency
src/index.js
Outdated
| speed: 0, | ||
| }); | ||
|
|
||
| const [effectiveChildren, setChildren] = useState(children); |
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.
Storing the children in state seems a bit over the top, could we not just add another option to state like showChildren: boolean and combine with keepChildrenOnClose to conditionally add the children in the JSX?
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.
Also, adding / removing children when opening / closing is causing more work for react as it's having to add / remove them from the DOM, so do you have any evidence of performance gains?
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.
Storing the children in state seems a bit over the top, could we not just add another option to state like showChildren: boolean and combine with keepChildrenOnClose to conditionally add the children in the JSX?
I guess adding showChildren will be just an extra prop. As most of the time lib user will pass isOpen value on showChildren. Also, it can't be handled outside as the effectiveChildren is set to null only after transition is finished. so then you will have to pass an onTransitionComplete prop, or onOpen/onClose prop to parent.
Also, adding / removing children when opening / closing is causing more work for react as it's having to add / remove them from the DOM, so do you have any evidence of performance gains?
So, this comes down to this question.
-> Do you want to pretender everything so when a user performs an action the transition is quick.?
-> Do you want to delegate the offscreen work when the user performs an action.?
On the first approach, you are paying the cost of rendering upfront for some content user may never see, probably on page load.
Plus as other things are going during page rendering, you are also adding some of the rendering time for an offscreen content.
This is valid on the update as well, why we need to do reconciliation (VDOM diffing) on offscreen content.
And on the second approach as onClick, you are doing relatively less work by shifting your work to onClick which will not be noticed. I feel this is a valid tradeoff to improve onscreen content performance. Sometime you may need a little bit of tinkering, but that you can do with keepChildrenOnClose prop.
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.
My main thoughts on this is accessibility and not hiding content from screen readers. Having a prop puts this in the hands of the developer, but I think having the children when closed should be the default.
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 for storing children in state, we can simply use a value stored in state to conditionally render the children and isOpen will override it.
I think storing children in state and removing them constantly would be inefficient and there is something we can do with a simple Boolean instead.
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.
My main thoughts on this is accessibility and not hiding content from screen readers. Having a prop puts this in the hands of the developer, but I think having the children when closed should be the default.
display: none and visibility: hidden elements are not accessible on-screen reader as well. In Ideal situation content wise we see should be similar to what screen reader reads. Providing them two versions is anti-pattern for accessibility. Exceptions are visual contents like img, icons etc. But textual content-wise it should be same for screen reader and normal user.
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 storing children in state and removing them constantly would be inefficient and there is something we can do with a simple Boolean instead.
Sure, I will update it boolean based.
src/index.js
Outdated
| } | ||
| return ( | ||
| <div | ||
| {...restProps} |
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 could lead to invalid props being passed down. I'm not sure it's needed as for custom styling you can just wrap it in a custom component which has it's own styling etc..
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.
My opinion:
This can be mentioned in the document. Forwarding non-component specific props to the root element can avoid the extra containers in dom elements if possible.
The actual use cases can definitely be solved other way as well. So I don't have a strong opinion on this. I will revert it back.
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.
Yeah I feel allowing for users to add their own class name to the wrapper would suffice.
src/index.js
Outdated
| import PropTypes from 'prop-types'; | ||
|
|
||
| const Collapsable = ({ | ||
| const Collapsible = ({ |
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.
Collapsable was intentional, you can spell it both ways and there is already a react-collapsible on NPM.
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 will change this back.
d2ff76b to
1585383
Compare
- Use boolean flag instead of storing children in state. - Remove spread props and rename the name to react-collapsable
1585383 to
abc4379
Compare
|
One other thing, can we update the read me to please? :) |
|
@dahliacreative Sorry missed this. Sure will update. |
| speed: 0 | ||
| }) | ||
|
|
||
| const [keepChildren, toggleChildren] = useState(isOpen) |
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.
can this just go into the state object above?
| if (!isOpen) { | ||
| content.current.style.visibility = 'hidden' | ||
|
|
||
| if (!keepChildrenOnClose) { |
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 would remove this and just add it to the conditional below {(keepChildren || keepChildrenOnClose) && children}
Perhaps also change keepChildren to something like displayChildren or shouldDisplayChildren feels a bit clearer.
| ? maxAnimationDuration | ||
| : time | ||
| content.current.style.visibility = 'visible' | ||
| toggleChildren(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.
Again if we put this in the state object you can just set this below.
Hey @dahliacreative. While searching for micro react component for similar use case found your library. Great work. 👍
This is a draft PR with few improvements. Please let me know what do you think. I will add the test cases afterwards.
Changes:
Also, I feel collapsable should be collapsible. Is this intentional? Should we keep a different name for it? I see there is already a library with react-collapsible name on npm.
Use this to ignore formatting changes.
https://github.com/dahliacreative/react-collapsable/pull/7/files?w=1