Skip to content

Don't misuse render prop pattern #1779

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

Merged
merged 1 commit into from
Apr 1, 2025
Merged

Don't misuse render prop pattern #1779

merged 1 commit into from
Apr 1, 2025

Conversation

axelboc
Copy link
Contributor

@axelboc axelboc commented Mar 27, 2025

I've relaxed the rule react/no-unstable-nested-components to allow the render prop pattern:

<ErrorBoundary
  fallbackRender={(args) => (
    <ErrorFallback className={visualizerStyles.vis} {...args} />
  )}
/>

The code above is okay (and unavoidable) as long as fallbackRender is used as a function inside ErrorBoundary - e.g. {fallbackRender(...args)}.

It's not okay when the render prop is used as a component. An example of this was the icon prop of the Btn component:

// Btn.tsx
const { icon: Icon } = props;
return <>{Icon && <Icon className={styles.icon} />}</>

<Btn
  // render prop but used as component
  icon={(iconProps) => (
    <FiItalic
      transform="skewX(20)"
      style={{ marginLeft: '-0.25em', marginRight: '0.0625rem' }}
      {...iconProps}
    />
  )}
/>

Unfortunately, react/no-unstable-nested-components cannot detect these two cases, which leads to false positives. Since the render prop pattern is legitimate and unavoidable in many cases, the rule could lead to worse solutions. So I've decided to turn on the rule's allowAsProp option, which allows passing "nested" components as props.

I'm also fixing the icon prop by turning it into a component prop:

// Btn.tsx
const { Icon } = props;
return <>{Icon && <Icon className={styles.icon} />}</>

<Btn
  // good component prop (icon is extracted into its own component)
  Icon={ErrorsIcon}
/>

@axelboc axelboc changed the base branch from main to extract-eslint March 27, 2025 13:39
@axelboc axelboc changed the title Render prop Don't misuse render prop pattern Mar 27, 2025
@axelboc axelboc requested a review from loichuder March 27, 2025 13:40
Base automatically changed from extract-eslint to main April 1, 2025 11:35
@axelboc axelboc merged commit e7333ab into main Apr 1, 2025
8 checks passed
@axelboc axelboc deleted the render-prop branch April 1, 2025 11:39
@loichuder
Copy link
Member

loichuder commented Apr 2, 2025

@axelboc
Copy link
Contributor Author

axelboc commented Apr 2, 2025

Meh 🤷 — to be honest, I'm considering moving away from eslint-plugin-react altogether. I've had to turn off another rule in MXCuBE because it can't actually do what it's supposed to. The last comment in the issue linked actually mentions another plugin called ESLint React, which seems to want to replace eslint-plugin-react. The rules look a lot smarter. To be continued...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants