Airbnb has adopted a Code of Conduct that applies to all open source projects. This addition ensures project participants understand community standards and provides clear reporting mechanisms for violations.
The ordering of the rules are currently not alphabetical, which can make it hard to tell whether there are rules missing or what's set for each rule from eslint-plugin-jsx-a11y.
This change alphabetizes the list so it's easier to compare to the [list of supported rules](https://github.com/jsx-eslint/eslint-plugin-jsx-a11y#supported-rules)
Fixes#2293
The reason for preferring object destructuring is quite narrow in scope. While this guide isn't intended to provide every possible reason for every preference, it perhaps should aim to provide a succinct and compelling reason. The current reasoning could be improved to meet this standard, so I'm proposing adding some additional information to clarify the benefits of what is an often controversial rule (controversial only because its introduction can require many changes in a mature codebase and has no auto fix available).
## Why is the change being made?
This change is made because the Airbnb documentation states to "avoid a
newline at the beginning of files", yet the code does not follow this.
## What has changed to address the problem?
This change fixes the `no-multiple-empty-lines` rule by setting max
beginning of file (`maxBOF`) to from 1 to 0.
## How was this change tested?
This change was tested with `npm test`.
## Related docs
https://github.com/airbnb/javascript#whitespace--no-multiple-empty-lines
The translation for Chinese (Simplified) is outdated. Changed to an up-to-date translation that synced with current English version, enhanced expressions for better readability, and also added notes of technical terms for Chinese readers.
It took me too long to realize that `"extends": "airbnb/hooks"` won't cut it, and that you need to include both `"extends": ["airbnb", "airbnb/hooks"]`. I think the docs should be explicit about this.
Previously `rules/strict.js` was only used by `eslint-config-airbnb`
and not base. This change reduces the duplication, and means the rule
is now set to 'never' as opposed to the ESLint default of 'safe'.
For users that left the `sourceType` at this preset's default of
`module` this change will be a no-op, since in module-mode the
`strict` rule always behaves as though 'never' had been set.
See:
https://eslint.org/docs/rules/strict#options
- adds warning on mixing `/` and `*` arithmetic operators
- removes warnings on mixing `**` and arithmetic operators
- removes warning on mixing `in` and `instanceof`
- removes warning on mixing `~` with other bitwise operators
- removes mixing of assignment operators with comparison operators
React Router passes a `staticContext` property to children to allow
signalling status codes and redirected URLs, by allowing children to
assign property values to it during render
Splitting up a component into multiple components can be useful for many reasons, including making important performance optimizations.
This lint rule discourages splitting up components because it forces you to: create a new file, copy over all the relevant imports, move over any local functions/values (or move them into yet another shared module), export the component (which makes your split off component now a public export), and re-import it into the new module.
Having multiple components per file shouldn't be much different from having multiple functions per file. And you shouldn't be forced to make a component a public export if it's really just an internal implementation detail of another component.
There's an argument to be made about _exporting_ multiple components, but mostly just in the context of React.lazy because it can only import default exports and you don't want something else in that file being statically imported (because that will prevent it from being code-split).
This style guide disallows the use of underscores in properties. However, the
Redux browser extension requires the use of a variable named
`__REDUX_DEVTOOLS_EXTENSION_COMPOSE__`. Since Redux is so popular with React,
it makes sense to allow this.
The examples and the reasoning indicates the author of the rule meant uppercase instead of capitalization. According to Wikipedia, capitalization is "writing a word with its first letter as a capital letter (uppercase letter) and the remaining letters in lower case", while the rule apparently tries to prevent exactly that.
This is semver-minor, because the `label-has-associated-control` rule is
the same as the `label-has-for` rule, theoretically. Both remain
enabled, but `label-has-for` will be disabled in the future if this rule
proves out.
This documents the enforced but currently undocumented `no-unused-vars` rule with a brief description, examples, and noting the `"ignoreRestSiblings": true` option.
We can use emoji for most of these flags, which should make
them look better on higher resolution displays and improve the
loading performance of the style guide a little.
The only flag we have here that does not have a good emoji yet
is the flag of Catalonia, which I left as-is for now.
https://emojipedia.org/flag-for-catalonia-esct/
This allows to import non-JavaScript files through the main export of a dependency's package.json.
The following would trigger an error before, but is fine with the new configuration:
```js
import 'roboto-fontface';
```
In eslint v4.18.0 separate settings are introduced for imports and exports for the `object-curly-newline` rule.
Without this change, there is different behavior when updating eslint to this version.
Adds a change to eslint-config-airbnb and eslint-config-airbnb-base to pull a list of rules from the project root and return a config with all rules turned off except the whitespace rules explicitly listed in the array. Also adds entry point data to readme.
Seen a few pull requests for the React style guide that try to introduce features that aren't yet in stage >= 3 (static class fields for i.e), so I've decided to add a comment to the beginning of the guide. Not sure if this is the right place to put it, but here it is.
This disclaimer might help:
1) give the community an idea what standards this guide is based on
2) prevent redundant pull requests
This updates the "trailing or leading underscores" guideline to suggest an better way to make properties hidden, as an alternative to just removing the underscore and making the property public.
fixed code example to meet the standard. `listingId` changed to `listingID`
See - Naming Conventions: Acronyms and initialisms should always be all capitalized, or all lowercased.
Also update code samples to highlight ways in which ES6
currently mishandles code when relying on Automatic Semicolon
Insertion
Revise hyperlink and example
- Use more up-to-date TC39 reference page on github.io
- wrap returnless function with side-effects in curly braces
also, clean up punctuation on a long comment line
Always use single-quoted strings
Except for when the string needs to be double-quoted because the string contains apostrophes
Update second example to incorporate IIFE
An IIFE is a more realistic example of code that developers may encounter which would raise an exception when relying completely upon ASI
It came from the special characters "M-BM-":
```
diff README.md README.md.new | cat -A
651c651$
< const foo = function uniqueMoreDescriptiveLexicalFoo() {$
---$
> M-BM- M-BM- const short = function longUniqueMoreDescriptiveLexicalFoo() {$
```
Requiring operators at the beginning of the line makes code more readable. When operators are on the left hand side they mirror the syntax of method chaining and it is easy to see the build of logic in a statement. This also updates the readme and fixes a style violation as a result of adding this rule in eslint-config-airbnb/test/test-base.js and eslint-config-airbnb-base/test/test-base.js.
Requiring operators at the beginning of the line makes code more readable. When operators are on the left hand side they mirror the syntax of method chaining and it is easy to see the build of logic in a statement.
Remove link to polish translation as it's outdated ( last commit from 2-3 years ago ).
For example in polish translation you can read that you should use one "var" keyword to declare your vars.
example:
```js
// źle ( bad )
var items = getItems();
var goSportsTeam = true;
var dragonball = 'z';
// dobrze ( good )
var items = getItems(),
goSportsTeam = true,
dragonball = 'z';
```
Attempts to clarify and address issue https://github.com/airbnb/javascript/issues/1508#issuecomment-319113807
Recommends yarn users to list peer dependencies and then install each peer dependency with specified version.
Prior yarn instructions led users to install the latest version of each peer dependency which, in some cases, led to errors if the latest version of a peer dependency did not have rules that this package uses.
There were links to eslint rules in a style that didn't match the style of the rest of the document. Specifically, most links in the document use the following style: "eslint: ['no-unneeded-ternary']", but there were badly styled links that looks like this: "eslint rule: ['no-unneeded-ternary']." Additionally, the badly styled links were on their own line, whereas all the other links are not placed on their own line.
Codify existing practices for writing Markdown in style guides and
enforce them via Markdownlint. A new npm script "lint" in the top level
package.json runs before tests or as the first step of the "travis"
script.
Only modify documents in cases where they had bugs or isolated cases of
inconsistency:
README.md: 10: MD007 Unordered list indentation
Inconsistent with all other top level lists
README.md: 10: MD032 Lists should be surrounded by blank lines
Some Markdown parsers don't handle this correctly
README.md: 3156-3161: MD005 Inconsistent indentation for list items at
the same level
Bug, looks like it's intended to be another list level but GitHub
renders it at the same level as the "No but seriously"
README.md & css-in-javascript/README.md: throughout: MD012 Multiple
consecutive blank lines
README.md: throughout: MD004 Unordered list style
Some nested lists used plusses, now everything consistently uses
dashes.
Otherwise, there is no way to write pure components that don't use state, refs, or lifecycle methods.
Stateless functions are not treated internally as pure components, and are rerendered every time.
This example makes me confused. I guess it missed the use of "children" of good code.
Is the example to explain that you should specify default values for non-required props?
Thanks
Part 7.1 says first why function declarations are not good and
after that it recommends to give a name to function expression.
The same order could be used in example too.
Some JavaScript versions interpret numbers as octal if they are written with a leading zero.
Babel interpreter throws with an `Invalid number` message.
- This commit provides a canonical way of describing
that the function body contains code of some sort.
- The convention chosen was '// ...'.
- This change is persisted throughout the readme file
where appropriate
This style guide recommends using `i += 1` over `i++`. Even though this
appears in a "bad" example, the example will be clearest if it is "bad"
in fewer ways.
The example showed a template string being used with no interpolation as "good". While it met the rule being described, it violated another rule for no reason.
People expect props like `style` and `className` to mean one specific
thing. Varying this API for a subset of your app makes the code less
readable and less maintainable, and may cause bugs.
It probably wouldn't be a bad idea for us to make a full pass on
updating the resources section, but I noticed the podcasts portion was
missing JS Air.
There has been some confusion around which language features should be
used and which should not be used yet. We have a pretty clear-cut rule
at Airbnb about this, which is do not use any TC39 proposals that have
not reached stage 3.
I considered putting this at the very top of the document, but I spotted
this section that seemed to fit.
Addresses #1057
I plan to add some information to this section that applies to ES6 and
everything following ES6. Since we already list this as ES6+ in the
table of contents, I figured it would be a good idea to make this match.
I preserved the anchor to avoid breaking links for folks.
As @ljharb pointed out, we are using some functions like `css()` and
`withStyles()`, but make no mention of what they are or where they come
from. Since they come from react-with-styles, let's make this clear.
We have been writing CSS in JavaScript and have developed a set of best
practices around this type of thing. I thought it would be nice to
publish this document alongside our other JavaScript style guide
documents.
This eslint rule does not enforce this style guide rule. I believe that
referencing it here will cause people to believe that this is enforced
via linting when it is not. As far as I know, there is no rule that
currently enforces this, but it would be nice to add one.
Broken and concatenated long strings are painful to work with and
produce less readable and searchable code. I think we should reverse
this rule.
Unfortunately, the max-len rule currently does not allow for this, but
there is currently a proposal to add an option to ESLint's max-len rule
that would allow for strings to be ignored.
https://github.com/eslint/eslint/issues/5805
There have also been discussions around performance of string
concatenation (https://github.com/airbnb/javascript/issues/40), but I
don't think that is very relevant here so I removed the links to them.
There has been some confusion around whether we should use single quotes
or template literals. To help avoid this confusion, I am adding a "bad"
example to the single quotes guideline. This rule is already enforced by
the quotes linter rule.
Generally, we want code to clearly express developer intention. Using
template literals communicates that you intend to use some of the
features that template literals offer (e.g. interpolation).
Fixes#992
In 53b4173b we removed the ES5 guide which contains a lot of guidelines
that are no longer very relevant for us. Similarly, some folks have
raised the relevance of these rules about reserved words, given that we
are now living in an age where ES3 support has mostly waned and
transpilers such as Babel are widely adopted and pave over these issues.
This seems like a good opportunity to simplify.
Fixes#61
I decided that `WrappedComponent` is clearer than `Component` here, so I
made the switch. I also realized that `WrappedComponent.name` might
still be undefined, so I added a fallback value of "Component".
This rule seems to be giving me errors for some places we have imported
devDependencies in our tests such as tape and eslint. This is actually
okay, so we just need to configure this rule to allow devDependencies
for tests.
While I was at it, I added some whitespace to improve readability and
reduce the likelihood of merge conflicts.
This rule was added by 1.10.0. I am setting it to be disabled because it
is very project-specific, so it doesn't make sense to enable it here.
https://github.com/benmosher/eslint-plugin-import/blob/master/docs/rules/no-restricted-paths.md
I found the sections of this file a little confusing, so I didn't know
where to put it. I think it would be better to simply alphabetize the
rules but I'll leave that for another time.
When I first added these, I left TODO notes to come back and evaluate
enabling them. I've gone through and think that we should definitely at
least enable the rules that enforce basic spec compliance (e.g. that
props don't have typos and that all of the required props are provided
for the given role). Since these deal with basic correctness, I don't
think we need to add any verbiage to the style guide for these rules.
We still have some more that we should evaluate and decide about
enabling here, but this is a good step in the right direction.
This was recently added to eslint-plugin-export. It enforces that
modules that only have a single export use a default export instead of a
named export. Since this is a breaking change and we want to cluster
breaking changes, I marked it as 0 for now with a TODO to enable when
that time comes.
I found these rules all smashed together with comments a little
difficult to mentally parse, partly because it is ambiguous which line
the comment applies to. Separating with some whitespace helps a lot
here, and will also reduce the likelihood of merge conflicts in this
code.
This new version renames most of the rules, and adds a number of new
rules that we will need to evaluate. I simply added them for now with
TODO comments so we remember to come back to them and make decisions
about each one. I also alphabetized the list to make it easier to find
what you are looking for.
These come from eslint-plugin-import. We've been using these rules for a
while at Airbnb so it seems like a good time to include them in this
configuration. We've found the no-unresolved rule in particular to be
very helpful when working across a large codebase.
https://github.com/benmosher/eslint-plugin-import
Since the no-unresolved rule works on commonjs, I decided to include it
in the node configuration as well.
I think there are some more rules from this plugin that are worth
enabling, but this seems like a great place to start.
In most cases we link to documentation on the eslint.org site instead of
on GitHub. I found a couple of stragglers and decided to make things a
little more consistent.
After digging into this rule a little more with @evcohen, we believe that
it is okay for images to have an empty string for alt text and have
updated the plugin to reflect that understanding. This commit bumps our
dependency on the rule to include this fix and updates our guideline to
match.
GitHub knows how to do JSX syntax highlighting. Since we are using JSX
in this document, I figured we might as well tell GitHub to highlight
the syntax as JSX here. This will lead to a better reading experience.
Screenreaders already announce `img` elements as images, so there is no
need to include this information in the alt text. This will give people
using assistive technologies a smoother experience.
We want our React apps to be accessible. One thing that developers can
do is properly use alt text on images. Thankfully, there is an ESLint
rule that will enforce these things for us.
I think it makes more sense to put static methods above the constructor
in classes. I would like to update the ESLint configuration to match
this, but it looks like the react/sort-comp rule does not support it
quite yet.
https://github.com/yannickcr/eslint-plugin-react/issues/128
As @kesne and @ljharb pointed out, this section was unclear about
whether or not you should always include blocks for all case clauses. To
make things clearer, I am adding a case clause that does not need a
block to the good example.
We decided that we should only require blocks for case clauses that
actually need them because it matches the as-needed spirit of section
3.8 ("Only quote properties that are invalid identifiers"). Perhaps if
there was an as-needed but consistent setting for the ESLint rule, we
would consider revising this a little, but this seems good enough for
now.
This commit adds guidance warning people to avoid lexical declarations
in case/default clauses and enables the corresponding ESLint rule.
http://eslint.org/docs/rules/no-case-declarations.html
We didn't have a section on switch statements yet, so I thought about
starting one. It seemed like it would best fit between section 15
(Comparison Operators & Equality) and section 16 (Blocks), but I didn't
want to mess up all of the following numberings, since people probably
have references to them. I considered adding this near the end to
minimize this effect, but it really seemed to belong near these other
things. I landed on appending it to Section 15 (Comparison Operators &
Equality) and I think it sorta fits there since switch statements are a
related concept.
[eslint] Add comment above `max-len` rule with link to its docs
[eslint] Change tab width for `max-len` rule from 4 to 2
[eslint] Replace double quotes around `max-len` with single quotes
[eslint] Use object form of `max-len` and include all of the options
I noticed that some newlines and indentation were a little inconsistent
in this file, so I decided to smooth things out a bit. This should help
people who decide to modify this document in the future. When
determining which is the "right" way to format these things, I decided
to use the style used by base readme as a guide.
I noticed a number of places in this document where code was being
referenced but it was not marked as such. Adding backticks will instruct
the markdown parser to format these bits as code, which should improve
the readability of this document.
isMounted is an anti-pattern [0], is not available when using ES6
classes, and is on its way to being officially deprecated.
eslint-plugin-react recently added the react/no-is-mounted rule in
3.12.0 that prevents its use.
[0]: https://facebook.github.io/react/blog/2015/12/16/ismounted-antipattern.html
Finishes #633
All of the other rules in this file are in alphabetical order, but this
one was added by c98990c0f out of order at the end. Keeping these in
alphabetical order will help developers find the rules that they are
looking for.
Enable [arrow-spacing](http://eslint.org/docs/rules/arrow-spacing.html) rule, code with space before/after arrow function's arrow is easier to read.
```js
() => {};
(a) => {};
a => a;
() => {'\n'};
()=> {}; /*error Missing space before =>*/
() =>{}; /*error Missing space after =>*/
(a)=> {}; /*error Missing space before =>*/
(a) =>{}; /*error Missing space after =>*/
a =>a; /*error Missing space after =>*/
a=> a; /*error Missing space before =>*/
()=> {'\n'}; /*error Missing space before =>*/
() =>{'\n'}; /*error Missing space after =>*/
```
Rule 18.5 [1] states that files shall end with a single newline
character. Until now, this was not checked because there was no such
option in eslint.
Since version 1.8.0, eslint provides the ability to do that. See pull
request on eslint [2] for details on implementation and usage. Let's use
it in airbnb eslint plugin now!
[1]: https://github.com/airbnb/javascript#18.5
[2]: https://github.com/eslint/eslint/pull/4266
Currently the way the rule is defined, mixing spaces and tabulations in
indentation is allowed. However, the comments and documents seems to say
the opposite.
This patchs turns the rule on so mixing spaces and tabs is NOT allowed.
Fixes: #539
All examples in README.md seem to agree on avoiding missing whitespaces
before keywords such as:
if (cond) {
}else { // no space before 'else'
}
try {
}catch (e) { // no space before 'catch'
}
This patchs adds the `space-before-keywords` rule as an error (as is
`space-after-keywords` already).
When there are static variables like `propTypes` and `defaultProps`, we shouldn't export them until we have actually set them onto the `Component`. This may change if the current ES7 proposal for static class properties gets accepts, and we update to support it.
Airbnb has adopted a Code of Conduct that we expect project participants to adhere to. Please [read the full Code of Conduct text](https://airbnb.io/codeofconduct/) so that you can understand what actions will and will not be tolerated. Report violations to the maintainers of this project or to [opensource-conduct@airbnb.com](mailto:opensource-conduct@airbnb.com).
Reports sent to [opensource-conduct@airbnb.com](mailto:opensource-conduct@airbnb.com) are received by Airbnb's open source code of conduct moderation team, which is composed of Airbnb employees. All communications are private and confidential.
*A mostly reasonable approach to CSS-in-JavaScript*
## Table of Contents
1. [Naming](#naming)
1. [Ordering](#ordering)
1. [Nesting](#nesting)
1. [Inline](#inline)
1. [Themes](#themes)
## Naming
- Use camelCase for object keys (i.e. "selectors").
> Why? We access these keys as properties on the `styles` object in the component, so it is most convenient to use camelCase.
```js
// bad
{
'bermuda-triangle': {
display: 'none',
},
}
// good
{
bermudaTriangle: {
display: 'none',
},
}
```
- Use an underscore for modifiers to other styles.
> Why? Similar to [BEM](https://getbem.com/introduction/), this naming convention makes it clear that the styles are intended to modify the element preceded by the underscore. Underscores do not need to be quoted, so they are preferred over other characters, such as dashes.
```js
// bad
{
bruceBanner: {
color: 'pink',
transition: 'color 10s',
},
bruceBannerTheHulk: {
color: 'green',
},
}
// good
{
bruceBanner: {
color: 'pink',
transition: 'color 10s',
},
bruceBanner_theHulk: {
color: 'green',
},
}
```
- Use `selectorName_fallback` for sets of fallback styles.
> Why? Similar to modifiers, keeping the naming consistent helps reveal the relationship of these styles to the styles that override them in more adequate browsers.
```js
// bad
{
muscles: {
display: 'flex',
},
muscles_sadBears: {
width: '100%',
},
}
// good
{
muscles: {
display: 'flex',
},
muscles_fallback: {
width: '100%',
},
}
```
- Use a separate selector for sets of fallback styles.
> Why? Keeping fallback styles contained in a separate object clarifies their purpose, which improves readability.
```js
// bad
{
muscles: {
display: 'flex',
},
left: {
flexGrow: 1,
display: 'inline-block',
},
right: {
display: 'inline-block',
},
}
// good
{
muscles: {
display: 'flex',
},
left: {
flexGrow: 1,
},
left_fallback: {
display: 'inline-block',
},
right_fallback: {
display: 'inline-block',
},
}
```
- Use device-agnostic names (e.g. "small", "medium", and "large") to name media query breakpoints.
> Why? Commonly used names like "phone", "tablet", and "desktop" do not match the characteristics of the devices in the real world. Using these names sets the wrong expectations.
```js
// bad
const breakpoints = {
mobile: '@media (max-width: 639px)',
tablet: '@media (max-width: 1047px)',
desktop: '@media (min-width: 1048px)',
};
// good
const breakpoints = {
small: '@media (max-width: 639px)',
medium: '@media (max-width: 1047px)',
large: '@media (min-width: 1048px)',
};
```
## Ordering
- Define styles after the component.
> Why? We use a higher-order component to theme our styles, which is naturally used after the component definition. Passing the styles object directly to this function reduces indirection.
```jsx
// bad
const styles = {
container: {
display: 'inline-block',
},
};
function MyComponent({ styles }) {
return (
<div {...css(styles.container)}>
Never doubt that a small group of thoughtful, committed citizens can
change the world. Indeed, it’s the only thing that ever has.
- Use an abstraction layer such as [react-with-styles](https://github.com/airbnb/react-with-styles) that enables theming. *react-with-styles gives us things like `withStyles()`, `ThemedStyleSheet`, and `css()` which are used in some of the examples in this document.*
> Why? It is useful to have a set of shared variables for styling your components. Using an abstraction layer makes this more convenient. Additionally, this can help prevent your components from being tightly coupled to any particular underlying implementation, which gives you more freedom.
- Define colors only in themes.
```js
// bad
export default withStyles(() => ({
chuckNorris: {
color: '#bada55',
},
}))(MyComponent);
// good
export default withStyles(({ color }) => ({
chuckNorris: {
color: color.badass,
},
}))(MyComponent);
```
- Define fonts only in themes.
```js
// bad
export default withStyles(() => ({
towerOfPisa: {
fontStyle: 'italic',
},
}))(MyComponent);
// good
export default withStyles(({ font }) => ({
towerOfPisa: {
fontStyle: font.italic,
},
}))(MyComponent);
```
- Define fonts as sets of related styles.
```js
// bad
export default withStyles(() => ({
towerOfPisa: {
fontFamily: 'Italiana, "Times New Roman", serif',
fontSize: '2em',
fontStyle: 'italic',
lineHeight: 1.5,
},
}))(MyComponent);
// good
export default withStyles(({ font }) => ({
towerOfPisa: {
...font.italian,
},
}))(MyComponent);
```
- Define base grid units in theme (either as a value or a function that takes a multiplier).
```js
// bad
export default withStyles(() => ({
rip: {
bottom: '-6912px', // 6 feet
},
}))(MyComponent);
// good
export default withStyles(({ units }) => ({
rip: {
bottom: units(864), // 6 feet, assuming our unit is 8px
},
}))(MyComponent);
// good
export default withStyles(({ unit }) => ({
rip: {
bottom: 864 * unit, // 6 feet, assuming our unit is 8px
},
}))(MyComponent);
```
- Define media queries only in themes.
```js
// bad
export default withStyles(() => ({
container: {
width: '100%',
'@media (max-width: 1047px)': {
width: '50%',
},
},
}))(MyComponent);
// good
export default withStyles(({ breakpoint }) => ({
container: {
width: '100%',
[breakpoint.medium]: {
width: '50%',
},
},
}))(MyComponent);
```
- Define tricky fallback properties in themes.
> Why? Many CSS-in-JavaScript implementations merge style objects together which makes specifying fallbacks for the same property (e.g. `display`) a little tricky. To keep the approach unified, put these fallbacks in the theme.
```js
// bad
export default withStyles(() => ({
.muscles {
display: 'flex',
},
.muscles_fallback {
'display ': 'table',
},
}))(MyComponent);
// good
export default withStyles(({ fallbacks }) => ({
.muscles {
display: 'flex',
},
.muscles_fallback {
[fallbacks.display]: 'table',
},
}))(MyComponent);
// good
export default withStyles(({ fallback }) => ({
.muscles {
display: 'flex',
},
.muscles_fallback {
[fallback('display')]: 'table',
},
}))(MyComponent);
```
- Create as few custom themes as possible. Many applications may only have one theme.
- Namespace custom theme settings under a nested object with a unique and descriptive key.
```js
// bad
ThemedStyleSheet.registerTheme('mySection', {
mySectionPrimaryColor: 'green',
});
// good
ThemedStyleSheet.registerTheme('mySection', {
mySection: {
primaryColor: 'green',
},
});
```
---
CSS puns adapted from [Saijo George](https://saijogeorge.com/css-puns/).
"comment":"MD022: Headers should be surrounded by blank lines.",
"comment":"Some headers have preceding HTML anchors. Unfortunate that we have to disable this, as it otherwise catches a real problem that trips up some Markdown renderers",
"blanks-around-headers":false,
"comment":"MD023: Headers must start at the beginning of the line.",
"header-start-left":true,
"comment":"MD024: Disallow multiple headers with the same content.",
"no-duplicate-header":true,
"comment":"MD025: Disallow multiple top level headers in the same document.",
"comment":"Gotta have a matching closing brace at the end.",
"single-h1":false,
"comment":"MD026: Disallow trailing punctuation in header.",
"comment":"You must have a semicolon after the ending closing brace.",
"no-trailing-punctuation":{
"punctuation":".,:!?"
},
"comment":"MD027: Dissalow multiple spaces after blockquote symbol",
"no-multiple-space-blockquote":true,
"comment":"MD028: Blank line inside blockquote",
"comment":"Some 'Why?' and 'Why not?' blocks are separated by a blank line",
"no-blanks-blockquote":false,
"comment":"MD029: Ordered list item prefix",
"ol-prefix":{
"style":"one"
},
"comment":"MD030: Spaces after list markers",
"list-marker-space":{
"ul_single":1,
"ol_single":1,
"ul_multi":1,
"ol_multi":1
},
"comment":"MD031: Fenced code blocks should be surrounded by blank lines",
"blanks-around-fences":true,
"comment":"MD032: Lists should be surrounded by blank lines",
"comment":"Some lists have preceding HTML anchors. Unfortunate that we have to disable this, as it otherwise catches a real problem that trips up some Markdown renderers",
"blanks-around-lists":false,
"comment":"MD033: Disallow inline HTML",
"comment":"HTML is needed for explicit anchors",
"no-inline-html":false,
"comment":"MD034: No bare URLs should be used",
"no-bare-urls":true,
"comment":"MD035: Horizontal rule style",
"hr-style":{
"style":"consistent"
},
"comment":"MD036: Do not use emphasis instead of a header.",
- [breaking] Prevent line breaks before and after `=` (#1710)
- [breaking] Add .mjs extension support (#1634)
- [breaking] enable `implicit-arrow-linebreak`
- [breaking] Enables `nonblock-statement-body-position` rule and adds link to guide (#1618)
- [breaking] `no-mixed-operators`: only warn on `**` and `%` mixed with arithmetic operators; removes violation against mixing common math operators. (#1611)
- [breaking] `import/named`: enable
- [breaking] `lines-between-class-members`: set to “always”
If using **yarn**, you can also use the shortcut described above if you have npm 5+ installed on your machine, as the command will detect that you are using yarn and will act accordingly.
Otherwise, run `npm info "eslint-config-airbnb-base@latest" peerDependencies` to list the peer dependencies and versions, then run `yarn add --dev <dependency>@<version>` for each listed peer dependency.
If using **npm < 5**, Linux/OSX users can run
```sh
(
export PKG=eslint-config-airbnb-base;
npm info "$PKG@latest" peerDependencies --json | command sed 's/[\{\},]//g ; s/: /@/g' | xargs npm install --save-dev "$PKG@latest"
If using **npm < 5**, Windows users can either install all the peer dependencies manually, or use the [install-peerdeps](https://github.com/nathanhleung/install-peerdeps) cli tool.
2. Add `"extends": "airbnb-base/legacy"` to your .eslintrc
See [Airbnb's overarching ESLint config](https://npmjs.com/eslint-config-airbnb), [Airbnb's JavaScript styleguide](https://github.com/airbnb/javascript), and the [ESlint config docs](https://eslint.org/docs/user-guide/configuring#extending-configuration-files) for more information.
### eslint-config-airbnb-base/whitespace
This entry point only errors on whitespace rules and sets all other rules to warnings. View the list of whitespace rules [here](https://github.com/airbnb/javascript/blob/master/packages/eslint-config-airbnb-base/whitespace.js).
## Improving this config
Consider adding test cases if you're making complicated rules changes, like anything involving regexes. Perhaps in a distant future, we could use literate programming to structure our README as test cases for our .eslintrc?
You can run tests with `npm test`.
You can make sure this module lints with itself using `npm run lint`.
message:'for..in loops iterate over the entire prototype chain, which is virtually never what you want. Use Object.{keys,values,entries}, and iterate over the resulting array.',
},
{
selector:'ForOfStatement',
message:'iterators/generators require regenerator-runtime, which is too heavyweight for this guide to allow them. Separately, loops should be avoided in favor of array iterations.',
},
{
selector:'LabeledStatement',
message:'Labels are a form of GOTO; using them makes code confusing and hard to maintain and understand.',
},
{
selector:'WithStatement',
message:'`with` is disallowed in strict mode because it makes code impossible to predict and optimize.',
},
],
// disallow space between function identifier and application
// deprecated in favor of func-call-spacing
'no-spaced-func':'off',
// disallow tab characters entirely
'no-tabs':'error',
// disallow the use of ternary operators
'no-ternary':'off',
// disallow trailing whitespace at the end of lines
- [deps] [breaking] update `eslint` to v3, `eslint-config-airbnb-base` to v5, `eslint-find-rules`, `eslint-plugin-import`, `eslint-plugin-jsx-a11y` to v2, `eslint-plugin-react` to v6, `tape`. drop node < 4 support.
- [patch] loosen `jsx-pascal-case` rule to allow all caps component names
- [tests] stop testing < node 4
- [tests] use `in-publish` because coffeescript screwed up the prepublish script for everyone
- [tests] Only run `eslint-find-rules` on prepublish, not in tests
- [tests] Even though the base config may not be up to date in the main package, let’s `npm link` the base package into the main one for the sake of travis-ci tests
- [docs] update the peer dep install command to dynamically look up the right version numbers when installing peer deps
- add `safe-publish-latest` to `prepublish`
9.0.1 / 2016-05-08
==================
- [patch] update `eslint-config-airbnb-base` to v3.0.1
9.0.0 / 2016-05-07
==================
- [breaking] update `eslint-config-airbnb-base` to v3
- [fix] disable [`no-confusing-arrow`][no-confusing-arrow] due to an `eslint` bug ([#752](https://github.com/airbnb/javascript/issues/752))
6.0.1 / 2016-02-21
==================
- [fix] disable [`newline-per-chained-call`][newline-per-chained-call] due to an `eslint` bug ([#748](https://github.com/airbnb/javascript/issues/748))
- [minor] Add [`prefer-arrow-callback`][prefer-arrow-callback] to ES6 rules (to match the guide) ([#677](https://github.com/airbnb/javascript/issues/677))
- [Tests] run `npm run lint` as part of tests; fix errors
- [Tests] use `parallelshell` to parallelize npm run-scripts
3.1.0 / 2016-01-07
==================
- [minor] Allow multiple stateless components in a single file
3.0.2 / 2016-01-06
==================
- [fix] Ignore URLs in [`max-len`][max-len] ([#664](https://github.com/airbnb/javascript/issues/664))
3.0.1 / 2016-01-06
==================
- [fix] because we use babel, keywords should not be quoted
- [breaking] Define a max line length of 100 characters ([#639](https://github.com/airbnb/javascript/issues/639))
- [breaking] [react] Minor cleanup for the React styleguide, add [`react/jsx-no-bind`][react/jsx-no-bind] ([#619](https://github.com/airbnb/javascript/issues/619))
- [breaking] [`space-in-parens`][space-in-parens]: disallow spaces in parens ([#594](https://github.com/airbnb/javascript/issues/594))
1.0.2 / 2015-11-25
==================
- [breaking] [`no-multiple-empty-lines`][no-multiple-empty-lines]: only allow 1 blank line at EOF ([#578](https://github.com/airbnb/javascript/issues/578))
This package provides Airbnb's .eslintrc as an extensible shared config.
## Usage
@@ -8,60 +10,78 @@ We export three ESLint configurations for your usage.
### eslint-config-airbnb
Our default export contains all of our ESLint rules, including EcmaScript 6+
and React. It requires `eslint`, `babel-eslint`, and `eslint-plugin-react`.
Our default export contains most of our ESLint rules, including ECMAScript 6+ and React. It requires `eslint`, `eslint-plugin-import`, `eslint-plugin-react`, `eslint-plugin-react-hooks`, and `eslint-plugin-jsx-a11y`. Note that it does not enable our React Hooks rules. To enable those, see the [`eslint-config-airbnb/hooks` section](#eslint-config-airbnbhooks).
If you don't need React, see [eslint-config-airbnb-base](https://npmjs.com/eslint-config-airbnb-base).
1. Install the correct versions of each package, which are listed by the command:
```sh
npm info "eslint-config-airbnb@latest" peerDependencies
```
If using **npm 5+**, use this shortcut
```sh
npx install-peerdeps --dev eslint-config-airbnb
```
If using **yarn**, you can also use the shortcut described above if you have npm 5+ installed on your machine, as the command will detect that you are using yarn and will act accordingly.
Otherwise, run `npm info "eslint-config-airbnb@latest" peerDependencies` to list the peer dependencies and versions, then run `yarn add --dev <dependency>@<version>` for each listed peer dependency.
If using **npm < 5**, Linux/OSX users can run
```sh
(
export PKG=eslint-config-airbnb;
npm info "$PKG@latest" peerDependencies --json | command sed 's/[\{\},]//g ; s/: /@/g' | xargs npm install --save-dev "$PKG@latest"
If using **npm < 5**, Windows users can either install all the peer dependencies manually, or use the [install-peerdeps](https://github.com/nathanhleung/install-peerdeps) cli tool.
This entry point enables the linting rules for React hooks (requires v16.8+). To use, add `"extends": ["airbnb", "airbnb/hooks"]` to your `.eslintrc`.
### eslint-config-airbnb/whitespace
This entry point only errors on whitespace rules and sets all other rules to warnings. View the list of whitespace rules [here](https://github.com/airbnb/javascript/blob/master/packages/eslint-config-airbnb/whitespace.js).
### eslint-config-airbnb/base
Lints ES6+ but does not lint React. Requires `eslint` and `babel-eslint`.
2. add `"extends": "airbnb/legacy"` to your .eslintrc
See [Airbnb's Javascript styleguide](https://github.com/airbnb/javascript) and
the [ESlint config docs](http://eslint.org/docs/user-guide/configuring#extending-configuration-files)
See [Airbnb's JavaScript styleguide](https://github.com/airbnb/javascript) and
the [ESlint config docs](https://eslint.org/docs/user-guide/configuring#extending-configuration-files)
for more information.
## Improving this config
Consider adding test cases if you're making complicated rules changes, like
anything involving regexes. Perhaps in a distant future, we could use literate
programming to structure our README as test cases for our .eslintrc?
Consider adding test cases if you're making complicated rules changes, like anything involving regexes. Perhaps in a distant future, we could use literate programming to structure our README as test cases for our .eslintrc?
You can run tests with `npm test`.
You can make sure this module lints with itself using `npm run lint`.
## Changelog
### 0.1.0
- switch to modular rules files courtesy the [eslint-config-default][ecd]
project and [@taion][taion]. [PR][pr-modular]
- export `eslint-config-airbnb/legacy` for ES5-only users.
`eslint-config-airbnb/legacy` does not require the `babel-eslint` parser.
"prepublishOnly":"eslint-find-rules --unused && npm test && safe-publish-latest",
"prepublish":"not-in-publish || npm run prepublishOnly",
"pretest":"npm run --silent lint",
"test":"npm run --silent tests-only",
"link:eslint":"cd node_modules/eslint && npm link --production && cd -",
"pretravis":"npm run link:eslint && cd ../eslint-config-airbnb-base && npm link --no-save eslint && npm install && npm link && cd - && npm link --no-save eslint-config-airbnb-base",
This style guide is mostly based on the standards that are currently prevalent in JavaScript, although some conventions (i.e async/await or static class fields) may still be included or prohibited on a case-by-case basis. Currently, anything prior to stage 3 is not included nor recommended in this guide.
## Table of Contents
1. [Basic Rules](#basic-rules)
1. [Class vs `React.createClass` vs stateless](#class-vs-reactcreateclass-vs-stateless)
1. [Mixins](#mixins)
1. [Naming](#naming)
1. [Declaration](#declaration)
1. [Alignment](#alignment)
1. [Quotes](#quotes)
1. [Spacing](#spacing)
1. [Props](#props)
1. [Refs](#refs)
1. [Parentheses](#parentheses)
1. [Tags](#tags)
1. [Methods](#methods)
1. [Ordering](#ordering)
1. [`isMounted`](#ismounted)
## Basic Rules
- Only include one React component per file.
- However, multiple [Stateless, or Pure, Components](https://facebook.github.io/react/docs/reusable-components.html#stateless-functions) are allowed per file. eslint: [`react/no-multi-comp`](https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/no-multi-comp.md#ignorestateless).
- Always use JSX syntax.
- Do not use `React.createElement` unless you're initializing the app from a file that is not JSX.
- Do not use `React.createElement` unless you’re initializing the app from a file that is not JSX.
- [`react/forbid-prop-types`](https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/forbid-prop-types.md) will allow `arrays` and `objects` only if it is explicitly noted what `array` and `object` contains, using `arrayOf`, `objectOf`, or `shape`.
## Class vs React.createClass
## Class vs `React.createClass` vs stateless
-Use class extends React.Component unless you have a very good reason to use mixins.
-If you have internal state and/or refs, prefer `class extends React.Component` over `React.createClass`. eslint: [`react/prefer-es6-class`](https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/prefer-es6-class.md) [`react/prefer-stateless-function`](https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/prefer-stateless-function.md)
```javascript
// bad
const Listing = React.createClass({
render() {
return <div />;
```jsx
// bad
const Listing = React.createClass({
// ...
render() {
return <div>{this.state.hello}</div>;
}
});
// good
class Listing extends React.Component {
// ...
render() {
return <div>{this.state.hello}</div>;
}
}
});
// good
class Listing extends React.Component {
render() {
return <div />;
```
And if you don’t have state or refs, prefer normal functions (not arrow functions) over classes:
```jsx
// bad
class Listing extends React.Component {
render() {
return <div>{this.props.hello}</div>;
}
}
}
```
// bad (relying on function name inference is discouraged)
const Listing = ({ hello }) => (
<div>{hello}</div>
);
// good
function Listing({ hello }) {
return <div>{hello}</div>;
}
```
## Mixins
- [Do not use mixins](https://facebook.github.io/react/blog/2016/07/13/mixins-considered-harmful.html).
> Why? Mixins introduce implicit dependencies, cause name clashes, and cause snowballing complexity. Most use cases for mixins can be accomplished in better ways via components, higher-order components, or utility modules.
## Naming
- **Extensions**: Use `.jsx` extension for React components.
- **Extensions**: Use `.jsx` extension for React components. eslint: [`react/jsx-filename-extension`](https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/jsx-filename-extension.md)
- **Filename**: Use PascalCase for filenames. E.g., `ReservationCard.jsx`.
- **Reference Naming**: Use PascalCase for React components and camelCase for their instances:
```javascript
- **Reference Naming**: Use PascalCase for React components and camelCase for their instances. eslint: [`react/jsx-pascal-case`](https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/jsx-pascal-case.md)
**Component Naming**: Use the filename as the component name. For example, `ReservationCard.jsx` should have a reference name of `ReservationCard`. However, for root components of a directory, use `index.jsx` as the filename and use the directory name as the component name:
```javascript
- **Component Naming**: Use the filename as the component name. For example, `ReservationCard.jsx` should have a reference name of `ReservationCard`. However, for root components of a directory, use `index.jsx` as the filename and use the directory name as the component name:
```jsx
// bad
const Footer = require('./Footer/Footer.jsx')
import Footer from './Footer/Footer';
// bad
const Footer = require('./Footer/index.jsx')
import Footer from './Footer/index';
// good
const Footer = require('./Footer')
import Footer from './Footer';
```
- **Higher-order Component Naming**: Use a composite of the higher-order component’s name and the passed-in component’s name as the `displayName` on the generated component. For example, the higher-order component `withFoo()`, when passed a component `Bar` should produce a component with a `displayName` of `withFoo(Bar)`.
> Why? A component’s `displayName` may be used by developer tools or in error messages, and having a value that clearly expresses this relationship helps people understand what is happening.
```jsx
// bad
export default function withFoo(WrappedComponent) {
return function WithFoo(props) {
return <WrappedComponent {...props} foo />;
}
}
// good
export default function withFoo(WrappedComponent) {
- **Props Naming**: Avoid using DOM component prop names for different purposes.
> Why? People expect props like `style` and `className` to mean one specific thing. Varying this API for a subset of your app makes the code less readable and less maintainable, and may cause bugs.
```jsx
// bad
<MyComponent style="fancy" />
// bad
<MyComponent className="fancy" />
// good
<MyComponent variant="fancy" />
```
## Declaration
- Do not use displayName for naming components. Instead, name the component by reference.
```javascript
- Do not use `displayName` for naming components. Instead, name the component by reference.
```jsx
// bad
export default React.createClass({
displayName: 'ReservationCard',
@@ -90,9 +171,10 @@
```
## Alignment
- Follow these alignment styles for JSX syntax
```javascript
- Follow these alignment styles for JSX syntax. eslint: [`react/jsx-closing-bracket-location`](https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/jsx-closing-bracket-location.md) [`react/jsx-closing-tag-location`](https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/jsx-closing-tag-location.md)
```jsx
// bad
<Foo superLongParam="bar"
anotherSuperLongParam="baz" />
@@ -111,13 +193,57 @@
superLongParam="bar"
anotherSuperLongParam="baz"
>
<Spazz />
<Quux />
</Foo>
// bad
{showButton &&
<Button />
}
// bad
{
showButton &&
<Button />
}
// good
{showButton && (
<Button />
)}
// good
{showButton && <Button />}
// good
{someReallyLongConditional
&& anotherLongConditional
&& (
<Foo
superLongParam="bar"
anotherSuperLongParam="baz"
/>
)
}
// good
{someConditional ? (
<Foo />
) : (
<Foo
superLongParam="bar"
anotherSuperLongParam="baz"
/>
)}
```
## Quotes
- Always use double quotes (`"`) for JSX attributes, but single quotes for all other JS.
```javascript
- Always use double quotes (`"`) for JSX attributes, but single quotes (`'`) for all other JS. eslint: [`jsx-quotes`](https://eslint.org/docs/rules/jsx-quotes)
> Why? Regular HTML attributes also typically use double quotes instead of single, so JSX attributes mirror this convention.
```jsx
// bad
<Foo bar='bar' />
@@ -132,8 +258,10 @@
```
## Spacing
- Always include a single space in your self-closing tag.
```javascript
- Always include a single space in your self-closing tag. eslint: [`no-multi-spaces`](https://eslint.org/docs/rules/no-multi-spaces), [`react/jsx-tag-spacing`](https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/jsx-tag-spacing.md)
```jsx
// bad
<Foo/>
@@ -148,9 +276,21 @@
<Foo />
```
- Do not pad JSX curly braces with spaces. eslint: [`react/jsx-curly-spacing`](https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/jsx-curly-spacing.md)
```jsx
// bad
<Foo bar={ baz } />
// good
<Foo bar={baz} />
```
## Props
- Always use camelCase for prop names.
```javascript
- Always use camelCase for prop names, or PascalCase if the prop value is a React component.
```jsx
// bad
<Foo
UserName="hello"
@@ -161,15 +301,210 @@
<Foo
userName="hello"
phoneNumber={12345678}
Component={SomeComponent}
/>
```
- Omit the value of the prop when it is explicitly `true`. eslint: [`react/jsx-boolean-value`](https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/jsx-boolean-value.md)
```jsx
// bad
<Foo
hidden={true}
/>
// good
<Foo
hidden
/>
// good
<Foo hidden />
```
- Always include an `alt` prop on `<img>` tags. If the image is presentational, `alt` can be an empty string or the `<img>` must have `role="presentation"`. eslint: [`jsx-a11y/alt-text`](https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/blob/master/docs/rules/alt-text.md)
```jsx
// bad
<img src="hello.jpg" />
// good
<img src="hello.jpg" alt="Me waving hello" />
// good
<img src="hello.jpg" alt="" />
// good
<img src="hello.jpg" role="presentation" />
```
- Do not use words like "image", "photo", or "picture" in `<img>` `alt` props. eslint: [`jsx-a11y/img-redundant-alt`](https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/blob/master/docs/rules/img-redundant-alt.md)
> Why? Screenreaders already announce `img` elements as images, so there is no need to include this information in the alt text.
```jsx
// bad
<img src="hello.jpg" alt="Picture of me waving hello" />
// good
<img src="hello.jpg" alt="Me waving hello" />
```
- Use only valid, non-abstract [ARIA roles](https://www.w3.org/TR/wai-aria/#usage_intro). eslint: [`jsx-a11y/aria-role`](https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/blob/master/docs/rules/aria-role.md)
```jsx
// bad - not an ARIA role
<div role="datepicker" />
// bad - abstract ARIA role
<div role="range" />
// good
<div role="button" />
```
- Do not use `accessKey` on elements. eslint: [`jsx-a11y/no-access-key`](https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/blob/master/docs/rules/no-access-key.md)
> Why? Inconsistencies between keyboard shortcuts and keyboard commands used by people using screenreaders and keyboards complicate accessibility.
```jsx
// bad
<div accessKey="h" />
// good
<div />
```
- Avoid using an array index as `key` prop, prefer a stable ID. eslint: [`react/no-array-index-key`](https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/no-array-index-key.md)
> Why? Not using a stable ID [is an anti-pattern](https://medium.com/@robinpokorny/index-as-a-key-is-an-anti-pattern-e0349aece318) because it can negatively impact performance and cause issues with component state.
We don’t recommend using indexes for keys if the order of items may change.
```jsx
// bad
{todos.map((todo, index) =>
<Todo
{...todo}
key={index}
/>
)}
// good
{todos.map(todo => (
<Todo
{...todo}
key={todo.id}
/>
))}
```
- Always define explicit defaultProps for all non-required props.
> Why? propTypes are a form of documentation, and providing defaultProps means the reader of your code doesn’t have to assume as much. In addition, it can mean that your code can omit certain type checks.
```jsx
// bad
function SFC({ foo, bar, children }) {
return <div>{foo}{bar}{children}</div>;
}
SFC.propTypes = {
foo: PropTypes.number.isRequired,
bar: PropTypes.string,
children: PropTypes.node,
};
// good
function SFC({ foo, bar, children }) {
return <div>{foo}{bar}{children}</div>;
}
SFC.propTypes = {
foo: PropTypes.number.isRequired,
bar: PropTypes.string,
children: PropTypes.node,
};
SFC.defaultProps = {
bar: '',
children: null,
};
```
- Use spread props sparingly.
> Why? Otherwise you’re more likely to pass unnecessary props down to components. And for React v15.6.1 and older, you could [pass invalid HTML attributes to the DOM](https://reactjs.org/blog/2017/09/08/dom-attributes-in-react-16.html).
Exceptions:
- HOCs that proxy down props and hoist propTypes
```jsx
function HOC(WrappedComponent) {
return class Proxy extends React.Component {
Proxy.propTypes = {
text: PropTypes.string,
isLoading: PropTypes.bool
};
render() {
return <WrappedComponent {...this.props} />
}
}
}
```
- Spreading objects with known, explicit props. This can be particularly useful when testing React components with Mocha’s beforeEach construct.
```jsx
export default function Foo {
const props = {
text: '',
isPublished: false
}
return (<div {...props} />);
}
```
Notes for use:
Filter out unnecessary props when possible. Also, use [prop-types-exact](https://www.npmjs.com/package/prop-types-exact) to help prevent bugs.
- Always use ref callbacks. eslint: [`react/no-string-refs`](https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/no-string-refs.md)
```jsx
// bad
<Foo
ref="myRef"
/>
// good
<Foo
ref={(ref) => { this.myRef = ref; }}
/>
```
## Parentheses
- Wrap JSX tags in parentheses when they span more than one line:
```javascript
/// bad
- Wrap JSX tags in parentheses when they span more than one line. eslint: [`react/jsx-wrap-multilines`](https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/jsx-wrap-multilines.md)
- Always self-close tags that have no children. eslint: [`react/self-closing-comp`](https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/self-closing-comp.md)
```jsx
// bad
<Foo className="stuff"></Foo>
<Foo variant="stuff"></Foo>
// good
<Foo className="stuff" />
<Foo variant="stuff" />
```
- If your component has multi-line properties, close its tag on a new line.
```javascript
- If your component has multiline properties, close its tag on a new line. eslint: [`react/jsx-closing-bracket-location`](https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/jsx-closing-bracket-location.md)
```jsx
// bad
<Foo
bar="bar"
@@ -215,13 +553,78 @@
```
## Methods
- Use arrow functions to close over local variables. It is handy when you need to pass additional data to an event handler. Although, make sure they [do not massively hurt performance](https://www.bignerdranch.com/blog/choosing-the-best-approach-for-react-event-handlers/), in particular when passed to custom components that might be PureComponents, because they will trigger a possibly needless rerender every time.
- Bind event handlers for the render method in the constructor. eslint: [`react/jsx-no-bind`](https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/jsx-no-bind.md)
> Why? A bind call in the render path creates a brand new function on every single render. Do not use arrow functions in class fields, because it makes them [challenging to test and debug, and can negatively impact performance](https://medium.com/@charpeni/arrow-functions-in-class-properties-might-not-be-as-great-as-we-think-3b3551c440b1), and because conceptually, class fields are for data, not logic.
- Do not use underscore prefix for internal methods of a React component.
```javascript
> Why? Underscore prefixes are sometimes used as a convention in other languages to denote privacy. But, unlike those languages, there is no native support for privacy in JavaScript, everything is public. Regardless of your intentions, adding underscore prefixes to your properties does not actually make them private, and any property (underscore-prefixed or not) should be treated as being public. See issues [#1024](https://github.com/airbnb/javascript/issues/1024), and [#490](https://github.com/airbnb/javascript/issues/490) for a more in-depth discussion.
```jsx
// bad
React.createClass({
_onClickSubmit() {
// do stuff
}
},
// other stuff
});
@@ -233,79 +636,122 @@
}
// other stuff
});
}
```
- Be sure to return a value in your `render` methods. eslint: [`react/require-render-return`](https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/require-render-return.md)
```jsx
// bad
render() {
(<div />);
}
// good
render() {
return (<div />);
}
```
## Ordering
- Ordering for class extends React.Component:
1. constructor
1. optional static methods
1. getChildContext
1. componentWillMount
1. componentDidMount
1. componentWillReceiveProps
1. shouldComponentUpdate
1. componentWillUpdate
1. componentDidUpdate
1. componentWillUnmount
1. *clickHandlers or eventHandlers* like onClickSubmit() or onChangeDescription()
1. *getter methods for render* like getSelectReason() or getFooterContent()
1. *Optional render methods* like renderNavigation() or renderProfilePicture()
1. render
- Ordering for `class extends React.Component`:
- How to define propTypes, defaultProps, contextTypes, etc...
1. optional `static` methods
1. `constructor`
1. `getChildContext`
1. `componentWillMount`
1. `componentDidMount`
1. `componentWillReceiveProps`
1. `shouldComponentUpdate`
1. `componentWillUpdate`
1. `componentDidUpdate`
1. `componentWillUnmount`
1. *event handlers starting with 'handle'* like `handleSubmit()` or `handleChangeDescription()`
1. *event handlers starting with 'on'* like `onClickSubmit()` or `onChangeDescription()`
1. *getter methods for `render`* like `getSelectReason()` or `getFooterContent()`
1. *optional render methods* like `renderNavigation()` or `renderProfilePicture()`
1. `render`
```javascript
import React, { Component, PropTypes } from 'react';
const propTypes = {
id: PropTypes.number.isRequired,
url: PropTypes.string.isRequired,
text: PropTypes.string,
};
const defaultProps = {
text: 'Hello World',
};
export default class Link extends Component {
static methodsAreOk() {
return true;
- How to define `propTypes`, `defaultProps`, `contextTypes`, etc...
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.