To read more articles like this, visit my blog
React is very unopinionated about how things should be structured. This is exactly why it’s our responsibility to keep our projects clean and maintainable.
Today, we will discuss some best practices to improve your React application’s health. These rules are widely accepted. As such, having this knowledge is imperative.
Everything will be shown with code, so buckle up!
1. Use JSX ShortHand
Try to use JSX shorthand for passing boolean variables. Let’s say you want to control the title visibility of a Navbar component.
Bad
return (
<Navbar showTitle={true} />
);
Good
return(
<Navbar showTitle />
)
2. Use Ternary Operators
Let’s say you want to show a user’s details based on role.
Bad
const { role } = user;
if(role === ADMIN) {
return <AdminUser />
}else{
return <NormalUser />
}
Good
const { role } = user;
return role === ADMIN ? <AdminUser /> : <NormalUser />
3. Take Advantage of Object Literals
Object literals can help make our code more readable. Let’s say you want to show three types of users based on their roles. You can’t use ternary because the number of options exceeds two.
Bad
const {role} = user
switch(role){
case ADMIN:
return <AdminUser />
case EMPLOYEE:
return <EmployeeUser />
case USER:
return <NormalUser />
}
Good
const {role} = user
const components = {
ADMIN: AdminUser,
EMPLOYEE: EmployeeUser,
USER: NormalUser
};
const Component = components[role];
return <Componenent />;
It looks much better now.
4. Use Fragments
Always use Fragment
over Div
. It keeps the code clean and is also beneficial for performance because one less node is created in the virtual DOM.
Bad
return (
<div>
<Component1 />
<Component2 />
<Component3 />
</div>
)
Good
return (
<>
<Component1 />
<Component2 />
<Component3 />
</>
)
5. Don't Define a Function Inside Render
Don’t define a function inside render. Try to keep the logic inside render to an absolute minimum.
Bad
return (
<button onClick={() => dispatch(ACTION_TO_SEND_DATA)}> // NOTICE HERE
This is a bad example
</button>
)
Good
const submitData = () => dispatch(ACTION_TO_SEND_DATA)
return (
<button onClick={submitData}>
This is a good example
</button>
)
6. Use Memo
React.PureComponent
and Memo
can significantly improve the performance of your application. They help us to avoid unnecessary rendering.
Bad
import React, { useState } from "react";
export const TestMemo = () => {
const [userName, setUserName] = useState("faisal");
const [count, setCount] = useState(0);
const increment = () => setCount((count) => count + 1);
return (
<>
<ChildrenComponent userName={userName} />
<button onClick={increment}> Increment </button>
</>
);
};
const ChildrenComponent =({ userName }) => {
console.log("rendered", userName);
return <div> {userName} </div>;
};
Although the child component should render only once because the value of count has nothing to do with the ChildComponent
. But, it renders each time you click on the button.
Good
Let’s edit the ChildrenComponent
to this:
import React ,{useState} from "react";
const ChildrenComponent = React.memo(({userName}) => {
console.log('rendered')
return <div> {userName}</div>
})
Now, no matter how many times you click on the button, it will render only when necessary.
7. Put CSS in JavaScript
Avoid raw JavaScript when writing React applications because organizing CSS is far harder than organizing JS.
Bad
// CSS FILE
.body {
height: 10px;
}
//JSX
return <div className='body'>
</div>
Good
const bodyStyle = {
height: "10px"
}
return <div style={bodyStyle}>
</div>
8. Use Object Destructuring
Use object destructuring to your advantage. Let’s say you need to show a user’s details.
Bad
return (
<>
<div> {user.name} </div>
<div> {user.age} </div>
<div> {user.profession} </div>
</>
)
Good
const { name, age, profession } = user;
return (
<>
<div> {name} </div>
<div> {age} </div>
<div> {profession} </div>
</>
)
9. String Props Don’t Need Curly Braces
When passing string props to a children component.
Bad
return(
<Navbar title={"My Special App"} />
)
Good
return(
<Navbar title="My Special App" />
)
10. Remove JS Code From JSX
Move any JS code out of JSX if that doesn’t serve any purpose of rendering or UI functionality.
Bad
return (
<ul>
{posts.map((post) => (
<li onClick={event => {
console.log(event.target, 'clicked!'); // <- THIS IS BAD
}} key={post.id}>{post.title}
</li>
))}
</ul>
);
Good
const onClickHandler = (event) => {
console.log(event.target, 'clicked!');
}
return (
<ul>
{posts.map((post) => (
<li onClick={onClickHandler} key={post.id}> {post.title} </li>
))}
</ul>
);
11. Use Template Literals
Use template literals to build large strings. Avoid using string concatenation. It’s nice and clean.
Bad
const userDetails = user.name + "'s profession is" + user.proffession
return (
<div> {userDetails} </div>
)
Good
const userDetails = `${user.name}'s profession is ${user.proffession}`
return (
<div> {userDetails} </div>
)
12. Import in Order
Always try to import things in a certain order. It improves code readability.
Bad
import React from 'react';
import ErrorImg from '../../assets/images/error.png';
import styled from 'styled-components/native';
import colors from '../../styles/colors';
import { PropTypes } from 'prop-types';
Good
The rule of thumb is to keep the import order like this:
Built-in
External
Internal
So the example above becomes:
import React from 'react';
import { PropTypes } from 'prop-types';
import styled from 'styled-components/native';
import ErrorImg from '../../assets/images/error.png';
import colors from '../../styles/colors';
13. Use Implicit return
Use the JavaScript feature implicit return
in writing beautiful code. Let’s say your function does a simple calculation and returns the result.
Bad
const add = (a, b) => {
return a + b;
}
Good
const add = (a, b) => a + b;
14. Component Naming
Always use PascalCase for components and camelCase for instances.
Bad
import reservationCard from './ReservationCard';
const ReservationItem = <ReservationCard />;
Good
import ReservationCard from './ReservationCard';
const reservationItem = <ReservationCard />;
15. Reserved Prop Naming
Don’t use DOM component prop names for passing props between components because others might not expect these names.
Bad
<MyComponent style="dark" />
<MyComponent className="dark" />
Good
<MyComponent variant="fancy" />
16. Quotes
Use double quotes for JSX attributes and single quotes for all other JS.
Bad
<Foo bar='bar' />
<Foo style={{ left: "20px" }} />
Good
<Foo bar="bar" />
<Foo style={{ left: '20px' }} />
17. Prop Naming
Always use camelCase for prop names or PascalCase if the prop value is a React component.
Bad
<Component
UserName="hello"
phone_number={12345678}
/>
Good
<MyComponent
userName="hello"
phoneNumber={12345678}
Component={SomeComponent}
/>
18. JSX in Parentheses
If your component spans more than one line, always wrap it in parentheses.
Bad
return <MyComponent variant="long">
<MyChild />
</MyComponent>;
Good
return (
<MyComponent variant="long">
<MyChild />
</MyComponent>
);
19. Self-Closing Tags
If your component doesn’t have any children, then use self-closing tags. It improves readability.
Bad
<SomeComponent variant="stuff"></SomeComponent>
Good
<SomeComponent variant="stuff" />
20. Underscore in Method Name
Do not use underscores in any internal React method.
Bad
const _onClickHandler = () => {
// do stuff
}
Good
const onClickHandler = () => {
// do stuff
}
21. Alt Prop
Always include an alt prop in your <img >
tags. And don’t use picture
or image
in your alt property
because the screenreaders already announce img
elements as images. No need to include that.
Bad
<img src="hello.jpg" />
<img src="hello.jpg" alt="Picture of me rowing a boat" />
Good
<img src="hello.jpg" alt="Me waving hello" />
Conclusion
There you go. Congratulations if you’ve made it this far! I hope you learned a thing or two from this article.
I hope you have a wonderful day! :D
Have something to say?
Resources
- Airbnb Guideline: https://github.com/airbnb/javascript/tree/master/react
Get in touch with me via LinkedIn or my Personal Website.
Top comments (16)
Many of these "blanket" rules: i think one should take a balanced approach, depending on when it's necessary. Your goods are not always good.
A number of these, if you use Prettier, eslint (or similar tools), they auto format these and/or warn you about them anyway.
Number 4 - Use Fragments:
I think as a blanket rule, this one is just wrong. There's a very big difference between
<div>
and<>
, at least for the css layout, which is important. Don't just follow the many hypes, such as automatically replacing your outermost<div>
with<>
. Example: say, outside of your component you have a flexbox. Thediv
will group its contents together,<>
will spit them out separately, they will not stick together. You'll end up with very different layouts.Number 5 - Don't define a function inside render:
-- Why? There are other conflicting software development principles which go against this. Example: don't declare variables unnecessarily, for single use, single use variables can make your codes clearer, or less clear. Depends on the case, balance it. If it is a short and simple js statement, inlining it can make your code clearer.
Same goes for Number 10: js inside jsx.
Use memo: Memo can easily cost you more than it saves.
11. Template literals
Whether template literals are cleaner, easier to read or safer: highly debatable. Depends on the specific case.
12. Import in Order
Counter-rule: don't spend time pedantically on things which the browser tools do (and should be doing) mostly automatically, such as: adding/removing imports automatically. Don't spend time reading, reviewing, discussing things like import's.
16. Quotes
This seems very personal. I think most kind-of de facto automatic code formatting tools convert all single quotes to double, or double to single anyway, in the recent years I've never worked on a project where they used both (except the cases where you have to use single quotes inside double quotes or the other way around, which is a different topic).
Yes... best practices are kindof lights in a runway.... not the runway itself.
And in my experience, yes you can always use the linter and prettier to fix most things.
But does it hurt to know why these rules are there in the first place? :)
Why? Indeed.
Many/most of the points in this article just declare a rule, but don't (really) explain (or prove) why... imho
;o
Agreed. But it's hard to prove these things :P
True :o) That's why many developers have been fighting for decades over these often somewhat arbitrary things.
Software development has been evolving, too, things have been changing over time.
And that's why Prettier, for example is such as good idea, i think, at least for one reason:
-- a professional team carefully selects one standard, then the whole community starts using the same format, it makes the code more uniform, easier to read for everyone, and therefore safer, too. It's the tool's task to auto-format, so we spend our time and effort on the actual coding, and not on the formatting of quotes and commas and spaces and discussing.
Using "style" intristic prop is a huge source of misstyling. Imagine you have 35 div's with same styling and you need to change just one or two properties of it. Writing a CSS class is way more better and convenient.
That was my initial thought as well.
Good article dood!
I love this article. Now a days instead of writing code, write a code with best practice is a far one.
I also share my experience and best practices in typescript and javascript to everyone for learning.
Keep it up!
If anyone would be willing to answer my questions about the seventh point in the article "Put CSS in JavaScript". I never understood why is JavaScript styling more sought after as CSS styling in React development. In my experience when I split the application into manageable components and pages CSS becomes much more manageable as pure JavaScript styling or styled components, even without introducing SCSS. And this rabbit hole just becomes even deeper when we introduce a component library such as Material UI. Why do they bother introducing quadrillion ways of styling their components instead of making it simpler with CSS styling, it just doesn't make any sense to me.
Really good tips mate.
Keep the good work ;) !
Great Post Faisal!❤👋
I Like how you explained with examples! 👏
Use memo in the early stage of development is anti-pattern and might cause you trouble. So, use it when you're really needed it.
I agree... this is just nice to know that you have it in your arsenal... when you need it.
Thank you for this nice article!
I have one question about point 7 though:
I always keep my JS separate from my CSS, so I put everything in its own file.
This, to me, feels like a nice separation of concerns and I found that there are quite a few articles that criticize CSS-in-JS:
dev.to/srmagura/why-were-breaking-...
dev.to/xantregodlike/css-in-js-why...
freecodecamp.org/news/you-dont-nee...
dev.to/macsikora/css-in-js-did-we-...
What is your stance regarding this topic? :)
Yes... but at the same time libraries like tailwind css has become much more popular...
I think this can vary from person to person. If separating css works for your project's scale and improves productivity, then why not?
There is no silver bullet! :D
Some comments may only be visible to logged-in visitors. Sign in to view all comments.