Indent props for readability and according to the line length.
ESLint: react/jsx-closing-bracket-location and react/jsx-closing-tag-location
⇣ Incorrect code for this rule:
<Season name="winter"
element="snow" />
⇡ Correct code for this rule:
<Season name="winter" element="snow" />
<Season name="winter" element="snow">
<SnowFlake amount={20} />
</Season>
Avoid using DOM component props names for different purposes. props
are expected to be like style
and className
to mean one specific thing. Varying this API for a subset of the app makes the code less readable and less maintainable, and may cause bugs.
⇣ Incorrect code for this rule:
<Component style="snow" />
<Component className="snow" />
⇡ Correct code for this rule:
<Component element="snow" />
Always use camelCase for prop names.
⇣ Incorrect code for this rule:
<Snow elementEffect="sparkling" frost_density={20} />
⇡ Correct code for this rule:
<Snow elementEffect="sparkling" frostDensity={20} />
Omit the value of the prop when it is explicitly true
.
ESLint: react/jsx-boolean-value
⇣ Incorrect code for this rule:
<Snow falling={true} />
⇡ Correct code for this rule:
<Snow falling />
⇢ Recommended code for this rule:
<Snow falling />
Avoid using an array index as key
prop, always use a unique ID. Not using a stable ID is an anti-pattern because it can negatively impact performance and cause issues with component state. Please see the official React documentation about keys.
ESLint: react/no-array-index-key
⇣ Incorrect code for this rule:
{
snow.map((snowflake, index) => <Snow {...snowflake} key={index} />);
}
⇡ Correct code for this rule:
{
snow.map((snowflake) => <Snow {...snowflake} key={snowflake.id} />);
}
Always define explicit defaultProps
for all non-required props. propTypes
are a form of documentation, and providing defaultProps
means the reader of the code doesn't have to assume as much. In addition, it can mean that the code can omit certain type checks.
⇣ Incorrect code for this rule:
function Snow({ density, season, snowflakes }) {
return (
<div>
{density}
{season}
{snowflakes}
</div>
);
}
Snow.propTypes = {
density: PropTypes.number.isRequired,
season: PropTypes.string,
snowflakes: PropTypes.node,
};
⇡ Correct code for this rule:
function Snow({ density, season, snowflakes }) {
return (
<div>
{density}
{season}
{snowflakes}
</div>
);
}
Snow.propTypes = {
density: PropTypes.number.isRequired,
season: PropTypes.string,
snowflakes: PropTypes.node,
};
Snow.defaultProps = {
season: "winter",
snowflakes: null,
};
Use spread props sparingly. Otherwise unnecessary props can be passed down to components. For React v15.6.1 and older, this can result in passing down invalid HTML attributes to the DOM.
HOCs that proxy down props and hoist propTypes
.
import React, { Component } from "react";
import PropTypes from "prop-types";
export const withSnow = (ComposedComponent) =>
class WithSnow extends Component {
static propTypes = {
season: PropTypes.string,
isFalling: PropTypes.bool,
};
render() {
return <ComposedComponent {...this.props} />;
}
};
function withSnow(ComposedComponent) {
return class WithSnow extends React.Component {
WithSnow.propTypes = {
season: PropTypes.string,
isFalling: PropTypes.bool
};
render() {
return <ComposedComponent {...this.props} />
}
}
}
Spreading objects with known, explicit props. This can be particularly useful when testing React components with 8's beforeEach
construct.
export default function Snow {
const props = {
season: "",
isFalling: false
}
return (<div {...props} />);
}
Filter out unnecessary props when possible to help prevent bugs e.g. by using helper libraries like prop-types-exact.
⇣ Incorrect code for this rule:
render() {
const { irrelevantProp, ...relevantProps } = this.props;
return <ComposedComponent {...this.props} />
}
⇡ Correct code for this rule:
render() {
const { irrelevantProp, ...relevantProps } = this.props;
return <ComposedComponent {...relevantProps} />
}
If it is necessary to use refs, always use ref callbacks.
ESLint: react/no-string-refs
⇣ Incorrect code for this rule:
<Snow ref="snowRef" />
⇡ Correct code for this rule:
<Snow
ref={(ref) => {
this.snowRef = ref;
}}
/>