React Style Guide
A guide for writing consistent and aesthetically pleasing React code.
Naming
Boolean state variables
- The state variable that hold a Boolean value must start with one of the
following prefixes:
- is + content explanation of the state value
- has + content explanation of the state value
- does + content explanation of the state value
- check + content explanation of the state value
// Bad
const [loading, setLoading] = useEffect(true);
// Good
const [isLoading, setIsLoading] = useEffect(true);- Filename: Use PascalCase for filenames. E.g.,
ReservationCard.tsx. - Reference Naming: Use PascalCase for React components and camelCase for
their instances. eslint:
react/jsx-pascal-case
// bad
import reservationCard from './ReservationCard';
// good
import ReservationCard from './ReservationCard';
// bad
const ReservationItem = <ReservationCard />;
// good
const reservationItem = <ReservationCard />;- Component Naming: Use the filename as the component name. For example,
ReservationCard.tsxshould have a reference name ofReservationCard. However, for root components of a directory, useindex.tsxas the filename and use the directory name as the component name:
// bad
import Footer from './Footer/Footer';
// bad
import Footer from './Footer/index';
// good
import Footer from './Footer';-
Props Naming: Avoid using DOM component prop names for different purposes.
Why? People expect props like
styleandclassNameto 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.
// bad
<MyComponent style="fancy"/>
// bad
<MyComponent className="fancy"/>
// good
<MyComponent variant="fancy"/>Declaration
-
A function must be doing only one thing and must be clearly named according to what it actually does.
-
If the number of the arguments passed to function is greater or equal to 3 (without a callback as argument), the arguments must be sent in an object.
-
Do not use
displayNamefor naming components. Instead, name the component by reference.
// bad
const comp = React.Component;
// good
import { Component } from 'react';Props
- Always use camelCase for prop names, or PascalCase if the prop value is a React component.
// bad
<Foo
UserName="hello"
phone_number={12345678}
/>
// good
<Foo
userName="hello"
phoneNumber={12345678}
Component={SomeComponent}
/>- Omit the value of the prop when it is explicitly
true. eslint:react/jsx-boolean-value
// bad
<Foo
hidden={true}
/>
// good
<Foo
hidden
/>
// good
<Foo hidden/>- Avoid using an array index as
keyprop, prefer a stable ID. eslint:react/no-array-index-key
Why? Not using a stable ID is an anti-pattern 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.
// bad
{
todos.map((todo, index) => <Todo {...todo} key={index} />);
}
// good
{
todos.map(todo => <Todo {...todo} key={todo.id} />);
}Favor functional components to Class components
- Functional component are much easier to read and test because they are plain
JavaScript functions without state or
lifecycle-hooks. You end up with less code. They help you to use best practices. - Read more about the topic here
Major functional programming principles
Avoid mutations
//Bad
const arr = [1, 2];
const tempArr = [];
arr.forEach(num => tempArr.push(num * 2));
//Good
const arr = [1, 2];
let tempArr = arr.map(num => num * 2);Avoid side-effects
Dont write functions dependent on the context, and don’t mutate the innerscope variables. Functions must be pure as much as possible.
// Bad
let y;
const fn = x => {
y = x * x;
};
fn(5);
y; // 25
// Good
const fn = x => x * x;
const y = fn(5); // 25Event handler function name
// bad
<div onClick={onClick}>Foo</div>
//good
<div onClick={handleClick}>Foo</div>
// bad
<form onSubmit={onSubmit}></form>
//good
<form onSubmit={handleSubmit}></form>Passing event handler functions
Avoid unneccasry callback calls, instead pass function directly.
//bad
<button onClick={(e) => handleClick(e)} />
//good
<button onClick={handleClick} />
//bad
<input onChange={(e) => handleChange(e)} />
//good
<input onChange={handleChange} />