-
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
Performance: Update usage of stateless, functional components to class-based components when event handlers are used #607
Comments
In the linked issue, it is noted that the linter suggesting to use a stateless component when there are instance methods is a bug. It goes on to suggest that having an event handler is actually having a stateful component, because So, we could just use class components when there are handlers. Because we need to pass prop values to the handler, I don't see a sane way around creating the function every time. There is a somewhat insane option IMO. Technically, you could use mutation and side-effects to avoid recreating the function, though I'm thinking it is worse than using a class component: let value
let onClick
const handleClick = (e) => {
if (onClick) onClick(e, value)
}
function DropdownItem(props) {
value = props.value
onClick = props.onClick
return (
<ElementType {...rest} className={classes} onClick={handleClick}>
{/* content */}
</ElementType>
)
} |
😟 that's a little rough haha. I'm also not sure it would work.
That makes a lot of sense to me as well. IMHO we should strive to make this library as efficient as possible so I think it's worth it to make these class-based components when there are event handlers involved. If you agree, I'm happy to figure out which components need updating and add them as a checklist at the top of this issue. |
Looks like best possible solution. |
Agreed, classes it is |
So close on this! |
Almost year and it's done 😄 |
Haha, I was just looking at this one... "So close..." 😄 |
Isn't it better to use react hooks now? |
@carkod It was 2016... Now there are React hooks indeed. |
See below for original conversation regarding "RFC: Memoize event handlers in stateless, functional components". These are the TODOs that came out of the discussion.
Functional components that need to be turned into a class (Found via grep:
const handle
):AccordionTitle
BreadcrumbSection
Card
DropdownItem
Form
Label
MenuItem
SearchResult
Step
Other places where functions are created within render (Found via grep:
const on[A-Z]
):Rating
Accordion
Search
-onMouseDown={e => e.preventDefault()}
that line can actually be removed I think. The analogous updates from this PR were carried over and this line should have been removed.Modal
- Moveref=
function tohandleRef
callbackDropdown
ref=
function inrender
tohandleRef
callbackref=
function inrenderSearchInput
tohandleSearchRef
callbackref=
function inrenderSearchSizer
tohandleSizerRef
callbackThere may be others so feel free to update this list!
Original discussion below regarding "RFC: Memoize event handlers in stateless, functional components"
Most of the conversation around this is in reference to actual components, not stateless functions. I've googled around a bit and the closest thing I've found to a discussion on this topic is: airbnb/javascript#784. This is also more of a general React question for you guys. I've run into this in my projects and haven't really settled on a great way to handle it.
I think using stateless, functional components is ideal and something we should strive for. However, initializing new arrays or functions inside a render (which we do) is considered an anti-pattern for performance reasons. Consider the
DropdownItem
component (pasting a simplified version here):In this case,
handleClick
will be a new function each time this function is called so the props for the underlying element are changing.One idea to solve this:Doesn't work, see below.This would mean that a new function would be created any time the props changed but that would be way less frequent than on every single render. Trying to get more granular (e.g. usingonClick
as a memoization key) would probably lead to hidden gotchas.This actually doesn't work since
props
will be a new object each time so the memoization comparison won't work.Definitely open to other ideas here!
The text was updated successfully, but these errors were encountered: