-
Class components vs Hooks ⬆
There are no preferences in using classes over hooks. So make sure you follow the project rules. The main principle is to be consistent. One exception is when the project team decides to move from classes to hooks or vice versa.
-
Component files ⬆
- Only one React component per file.
- As an exception multiple small pure or stateless components are allowed in one file.
- Only one React component per file.
-
Naming Style ⬆
- Always use
.jsx
|.tsx
extensions. - Use UpperCamelCase as a components name.
- Use lowerCamelCase for prop names.
- It's recommended to use suffixes
Component
orContainer
for explicit definition of "dumb" and "smart" components:UserProfileComponent
andUserProfileContainer
. - Component name should be the same as the file name. This means that the use of
index
files is forbidden for components. It's easier to find components by filename rather than by folder name. - Component filenames should be in UpperCamelCase. It's allowed to use dots (
.
) to explicitly mention type of component:Dashboard.component.tsx
,UserProfile.container.tsx
. - Props and state interface definitions shouldn't be prefixed with
I
. Use UpperCamelCase instead. - Exported props types should have a suffix
Props
:ProgressBarProps
. Not exported props and state interfaces recommended namingProps
andState
respectively.
- Always use
-
Horizontal spacing and indentation ⬆
- Each nested component increases indentation by ** 2 ** spaces relative to the parent component.
- There is no space after opening curly brace (
{
) and before closing curly brace (}
) when wrapping JS expression in JSX:
<Component user={someUser} /> {isLoading && <Loader />}
- Before self-closing
/>
tag should be a single space.
-
Line breaks ⬆
- Component with a single prop without children should take a single line.
- Component with more than one prop or with children must be multiline
- Each prop should start from the new line
- Children should start from the new line
- Closing bracket of the opening tag
>
& self-closing/>
tag should be placed on the new line:<Button size='small' onPress={onPress} > {buttonText} </Button> <UserProfile name='Boris' lastName='Blade' />
- Both single line & multiline JSX are wrapped in parentheses. After opening parenthesis
(
and before closing)
should be a line break.return ( <CustomComponent prop1={value1} prop2={value2} /> );
const MyComponent = (props) => ( <UserProfile {...props} /> );
-
Props ⬆
- Use single quotes
'
for jsx attributes. - Do not use braces
{}
for string literals unless it's JS expression. - Use explicit value for boolean props even if default value is
true
.<Component enabled={true} />
- Do not inline object or array creation inside jsx. Prepare the data before
return
statement. - Inline styles are forbidden. Use
Stylesheet.create
or its analogue. - Destruct props and state before usage.
- Use single quotes
-
Naming of component members ⬆
- Methods that return React Node must start with
render
prefix:renderTableFooter()
. - Event handlers must start with
on
prefix:onSettingsPress()
.
- Methods that return React Node must start with
-
Component members ordering ⬆
- Members of class component should be in following order:
static
fields and methodsconstructor
- component lifecycle methods (
componentDidMount
,shouldComponentUpdate
, etc) - utility methods (not event handlers, nor render methods)
- event handlers
- render methods like
renderProfilePicture()
- render
- Members of class component should be in following order:
-
Recommended packages ⬆
- To enforce code consistency & avoid potential bugs, the usage of ESLint is strongly recommended.
- It is recommended to use eslint-plugin-react package in order for ESLint to recognize React semantics.
- When using TypeScript, using typescript-eslint is a necessity for ESLint and TypeScript working together.
- The preferred format for
.eslintrc
config file is.json
.
-
ESLint setup via --init command ⬆
If you prefer setting up the ESLint configuration by using the
npx eslint --init
command, here's the recommended selection:- How would you like to use ESLint? -> To check syntax, find problems, and enforce code style
- What type of modules does your project use? -> JavaScript modules (import/export)
- Which framework does your project use? -> React
- Does your project use TypeScript? -> Depends on the project
- Where does your code run? -> depends on the project
- How would you like to define a style for your project? -> Use a popular style guide
- Which style guide do you want to follow? -> Airbnb
- What format do you want your config file to be in? -> JSON
This setup automatically will install the packages mentioned in the Recommended packages section. However, this setup will still cause error even in the basic create-react-app project. The additional steps to make sure that ESLint is running smoothly with React application are listed below.
Rules for React Hook
- install eslint-plugin-react-hooks to enforce hooks rules that were set by React team:
npm install eslint-plugin-react-hooks --save-dev
- add newly installed plugin to .eslintrc.json file:
{ // ... "plugins": [ // ... "react-hooks" ], }
Guide for JavaScript project
- install eslint-plugin-import package, in order to prevent issues with misspelling of file paths and import names:
npm install eslint-plugin-import --save-dev
- add
.eslintignore
file to avoid checking some file types. We recommend skipping.css
&.svg
, add the following code inside file to do that:*.css *.svg
- add the overrides section to .eslintrc.json file:
{ // ... "overrides": [ { "files": [ "**/*.spec.js", "**/*.spec.jsx", "**/*.test.js", "**/*.test.jsx" ], "env": { "jest": true } } ] }
Guide for Typescript project
- Add following rules to
.eslintrc.json
:{ // ... "rules": { // fix 'React was used before it was defined' error "no-use-before-define": "off", "@typescript-eslint/no-use-before-define": ["error"], // fix 'JSX not allowed in files with extension ‘. tsx’' error "react/jsx-filename-extension": [ "warn", {"extensions": [".tsx"]} ], // fix ‘Enum is already declared in the upper scope' error "no-shadow": "off", "@typescript-eslint/no-shadow": ["error"], // fix 'import/extensions' error "import/extensions": [ "error", "ignorePackages", { "ts": "never", "tsx": "never" } ], } }
- install eslint-import-resolver-typescript package, in order to prevent issues with misspelling of file paths and import names:
also add a
npm install eslint-import-resolver-typescript --save-dev
settings
property to.eslintrc.json
:{ // ... "settings": { "import/resolver": { "typescript": {} } } }
- add
.eslintignore
file to avoid checking some file types. We recommend skipping.css
&.svg
, add the following code inside file to do that:*.css *.svg
- add
@typescript-eslint/recommended
plugin to the extends property inside.eslintrc.json
:{ // ... "extends": [ // ... "plugin:@typescript-eslint/recommended" ], }
No React import with New JSX Transform
- if you're using React 17 and prefer not to include the React import in JSX files ,
disable following rules in
.eslintrc.json
file:{ // ... "rules": { // ... "react/jsx-uses-react": "off", "react/react-in-jsx-scope": "off" } }