Skip to content
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

Add rule to forbid className and style being passed to Components #703

Merged
merged 3 commits into from
Aug 10, 2016

Conversation

lencioni
Copy link
Collaborator

@lencioni lencioni commented Jul 24, 2016

Passing className or style to your Components is a source of much
hidden complexity that can be solved either by using a wrapper to add
styling or by adding props for specific styling. This rule aims at
preventing these props from being passed to your Components, to help
minimize hidden complexity.

The original issue proposed having this rule check propTypes. I
considered that route, but I worry that it won't be as effective for
people who do not have every prop used by the component listed in the
propTypes. Additionally, propTypes seem to have waning interest from the
React team in favor of Flow annotations, so I think in the long run
checking for this at the callsite will be more stable.

More information can be found by reading:

https://medium.com/brigade-engineering/don-t-pass-css-classes-between-components-e9f7ab192785

Also:

https://twitter.com/sebmarkbage/status/598971268403073024

Fixes #314

cc: @janpaul123 @sebmarkbage


```js
...
"forbid-component-props": [<enabled>, { "forbid": [<string>] }]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

would this not need a "react/" prefix?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, I think so. I was copying how it is in other rules documentation though so we should probably fix them all at the same time.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sounds good.

// Rule Definition
// ------------------------------------------------------------------------------

module.exports = function(context) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should use the new eslint rule format

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the heads up! This PR has been updated.


### `forbid`

An array of strings, with the names of props that are forbidden.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If i want to forbid certain props on Components, but not forbid className/style, how do I do that?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You would set the forbid option to include the props that you want to forbid and not include className/style. This is identical to forbid-prop-types.

https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/forbid-prop-types.md

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It might be good to explicitly note that the default value of this option is ['className', 'style']

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure, done!

lencioni and others added 3 commits July 28, 2016 10:43
Passing `className` or `style` to your Components is a source of much
hidden complexity that can be solved either by using a wrapper to add
styling or by adding props for specific styling. This rule aims at
preventing these props from being passed to your Components, to help
minimize hidden complexity.

The original issue proposed having this rule check propTypes. I
considered that route, but I worry that it won't be as effective for
people who do not have every prop used by the component listed in the
propTypes. Additionally, propTypes seem to have waning interest from the
React team in favor of Flow annotations, so I think in the long run
checking for this at the callsite will be more stable.

More information can be found by reading:

  https://medium.com/brigade-engineering/don-t-pass-css-classes-between-components-e9f7ab192785

Also:

  https://twitter.com/sebmarkbage/status/598971268403073024

Fixes jsx-eslint#314
I updated this via the codemod from eslint-transforms. [I ran into some
errors getting eslint-transforms to run correctly as described][0], but
I was able to find a workaround by running the jscodeshift command
directly.

[0]: eslint/eslint-transforms#2 (comment)

This is a completely automated change.
Listing the defaults in the documentation for these rules makes it
clearer how they work.
@lencioni
Copy link
Collaborator Author

lencioni commented Aug 5, 2016

@yannickcr @ljharb anything else you'd like to see on this before we merge it in?

@lencioni
Copy link
Collaborator Author

lencioni commented Aug 7, 2016

I plan to merge this soon unless I hear otherwise.

@lencioni lencioni merged commit 9d326ab into jsx-eslint:master Aug 10, 2016
@lencioni lencioni deleted the forbid-component-props branch August 10, 2016 19:12
@cristian-sima
Copy link

This rule is nice, but what if we are required by default to pass the className as a prop. Let's take for instance, the react-modal case:

      <Modal
        className="Modal__Bootstrap modal-dialog"
        onRequestClose={this.handleCloseModal}
        isOpen>

@ljharb
Copy link
Member

ljharb commented Aug 16, 2016

Per the info in the OP, you'd simply not use the rule in that case - the idea is that passing a className is an antipattern, and you'd want to avoid it.

@cristian-sima
Copy link

Thanks for your reply.

In order to not use it, I have to disable the rule, which in turn may be contra-productive, as I can have in the same function or file other components which should indeed not receive the className or style props.

I propose a different approach. What about introducing an option to tell the rule which components should be ignored.

As in my example, react-modal has always the Modal component. I can specify eslint to ignore any component with the name Modal.

Well, yes this approach has a down-side as I may write in the future components with that name, but I think is less likely.

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

Successfully merging this pull request may close these issues.

None yet

4 participants