React Style Guide
React is one of the most popular front-end frameworks for JavaScript. Unlike other frameworks like Angular, it is very unopinionated. Therefore, it is up to you to decide how you want to write or structure your React code. React has plenty of uses, but it can be difficult to initially get to grips with. Here we have highlighted some of the key practices that are worth following
Naming
- List itemExtensions: Use .jsx extension for React components. eslint: react/jsx-filename-extension
- Filename: Use PascalCase for filenames. E.g., ReservationCard.jsx.
- Reference Naming: Use PascalCase for React components and camelCase for their instances.
- 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.
- 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).
Declaration
Do not use displayName for naming components. Instead, name the component by reference. Don't do this
export default React.createClass({
displayName: "ReservationCard",
// stuff goes here
});
Instead do this:
export default function ReservationCard(props) {
return ()
}
Avoid Repetitive Code
If you notice you are writing duplicated code, convert it into components that can be reused.
For example, it makes more sense to create a component for your navigation menu instead of repeatedly writing the code in every component that requires a menu.
That’s the advantage of a component-based architecture. You can break down your project into small components you can reuse across your application.
Alignment
Follow these alignment styles for JSX syntax. eslint: react/jsx-closing-bracket-location react/jsx-closing-tag-location
// bad
<Foo superLongParam="bar"
anotherSuperLongParam="baz" />
// good
<Foo
superLongParam="bar"
anotherSuperLongParam="baz"
/>
// if props fit in one line then keep it on the same line
<Foo bar="bar" />
// children get indented normally
<Foo
superLongParam="bar"
anotherSuperLongParam="baz"
>
<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"
/>
)}
Opt for Fragments Instead of Divs Where Possible
React components need to return code wrapped in a single tag usually a <div>
or a React fragment. You should opt for fragments where possible.
Using <div>
increases the DOM size, especially in huge projects since the more tags or DOM nodes you have, the more memory your website needs and the more power a browser uses to load your website. This leads to lower page speed and potentially poor user experience.
One example of eliminating unnecessary <div>
tags is not using them when returning a single element.
const Button = () => {
return <button>Display</button>;
};
Avoid Using State (If Possible)
React state keeps track of the data which when changed triggers the React component to re-render. When building React applications, avoid using state as much as possible since the more state you use, the more data you have to keep track of across your app.
One way of minimizing the use of state is by declaring it only when necessary. For instance, if you are fetching user data from an API, store the whole user object in the state instead of storing the individual properties.
Instead of doing this:
const [username, setusername] = useState("");
const [password, setpassword] = useState("");
Do this:
const [user, setuser] = useState({});
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
/>
// very good
<Foo hidden />
Avoid Using Indexes as Key Props
React uses keys to uniquely identify items in an array. With keys, React can pinpoint which item has been changed, added, or removed from the array.
Most of the time when rendering arrays, you might use the index as the key.
const Items = () => {
const arr = ["item1", "item2", "item3", "item4", "item5"];
return (
<>
{arr.map((elem, index) => {
<li key={index}>{elem}</li>;
})}
</>
);
};
While this sometimes works, using the index as a key can introduce issues especially if the list is expected to change. Consider this list.
const arr = ["item1", "item2", "item3", "item4", "item5"];
Currently, the first list item, “Item1” is at index zero, but if you added another item at the beginning of the list, the “Item1” index would change to 1 which changes the behavior of your array. The solution is to use a unique value as the index to ensure that the identity of the list item is maintained.
Use Object Destructuring For Props
Instead of passing the props object, use object destructuring to pass the prop name. This discards the need to refer to the props object each time you need to use it.
For example, the following is a component that uses props as is.
const Button = (props) => {
return <button>{props.text}</button>;
};
With object destructuring, you refer to the text directly.
const Button = ({ text }) => {
return <button>{text}</button>;
};
Refs
Always use ref callbacks. eslint: react/no-string-refs
// bad
<Foo
ref="myRef"
/>
// good
<Foo
ref={(ref) => { this.myRef = ref; }}
/>
Parentheses
Wrap JSX tags in parentheses when they span more than one line. eslint: react/jsx-wrap-multilines
// bad
render() {
return <MyComponent variant="long body" foo="bar">
<MyChild />
</MyComponent>;
}
// good
render() {
return (
<MyComponent variant="long body" foo="bar">
<MyChild />
</MyComponent>
);
}
// good, when single line
render() {
const body = <div>hello</div>;
return <MyComponent>{body}</MyComponent>;
}
Dynamically Render Arrays Using Map
Use map() to dynamically render repeated HTML blocks. For example, you can use map() to render a list of items in <li>
tags.
const Items = () => {
const arr = ["item1", "item2", "item3", "item4", "item5"];
return (
<>
{arr.map((elem, index) => {
<li key={elem + index}>{elem}</li>;
})}
</>
);
};
For comparison purposes, here is how you can render the list without map(). This approach is very repetitive.
const List = () => {
return (
<ul>
<li>Item1</li>
<li>Item2</li>
<li>Item3</li>
<li>Item4</li>
<li>Item5</li>
</ul>
);
};
Write Tests for Each React Component
Write tests for the components you create as it reduces the possibilities of errors. Testing ensures that the components are behaving as you would expect. One of the most common testing frameworks for React is Jest, and it provides an environment where you can execute your tests.
React Is a Powerful Tool, But You Must Follow Certain Practices
Although React is somewhat flexible in terms of how you can use it, following specific practices will help you get the most out of your experience.