Skip to content

[BUG] - Button's startContent and endContent are cloning on every minimal button prop changesΒ #6207

@albannurkollari

Description

@albannurkollari

HeroUI Version

2.8.7

Describe the bug

Before I describe the issue, I want to verify whether my notion what is considered bug or not. Thus, close this issue if you don't deem it as one.

Bug:
When rendering a Button component and passing it a startContent or endContent of React element type, e.g. an icon, I noticed that the component re-renders on hover of the button (it's parent). Upon inspection I found out these lines of code that produce the undesired outcome. Bare in mind I tried this with even a blank rendering component such as:

Edit: Since GitHub has an issue rendering permalink lines, the codeblock I was referring in the aforementioned file starts from getIconClone

function MyIcon() {
  console.log('rendering icon');

  return null;
}


export function TestButton() {
  return <Button startContent={<MyIcon />} />;
}

Is this behavior intentional and if so why and what are the considerations to account for?

I have a use case where the SVG Icon component I pass to either start|end content of the button, has an imperative handle that I'm supposed to trigger it's animation on demand. Then I realized that every hover I did on the button itself, was rerendering my complex SVG Icon component...which is a performance killer to say the least.
Now there are ways to alleviate this from my end via React.memo and useMemo but the question is why should I if my component's props are unchanged. Should button itself memoize it internally and only rerender if either of the props are changed?

Your Example Website or App

No response

Steps to Reproduce the Bug or Issue

  1. Create a React layout/component and render a Button component.
  2. Add either startContent or endContent (no need for both), but make sure its a custom component of yours.
  3. Add console.log in it's body.
  4. Hover in/out on the button during runtime.
  5. Notice the logging in DevTools on every hover of the parent Button component.

Expected behavior

Button component should not clone its start|end content components on every render instead should opt-in to memoize it internally and only rerender if it's props are changed.

Screenshots or Videos

No response

Operating System Version

Windows 11

Browser

Chrome

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions