ReactJS Best Practices Every Developer Should Follow
π ReactJS Best Practices Every Developer Should Follow (with Examples & Bonus Tips!) π»β¨
ReactJS has become the backbone of modern web apps β but writing efficient, maintainable React code requires more than just useState
and useEffect
. Whether youβre a beginner or a seasoned developer, following best practices makes your app faster, cleaner, and easier to scale. Letβs level up your React game with these battle-tested principles, practical examples, and some bonus pro tips! π―π₯
β 1οΈβ£ Keep Components Small & Focused
π Rule: One component = one responsibility.
Large components are hard to read, debug, and test. Break them down into reusable, focused pieces.
Example:
// β Bad: One large component
function UserProfile({ user }) {
return (
<div>
<h1>{user.name}</h1>
<p>{user.bio}</p>
<button onClick={logout}>Logout</button>
</div>
);
}
// β
Good: Split into small components
function UserProfile({ user }) {
return (
<div>
<UserName name={user.name} />
<UserBio bio={user.bio} />
<LogoutButton />
</div>
);
}
function UserName({ name }) {
return <h1>{name}</h1>;
}
function UserBio({ bio }) {
return <p>{bio}</p>;
}
function LogoutButton() {
return <button onClick={logout}>Logout</button>;
}
β 2οΈβ£ Use Functional Components & Hooks
π Why: Hooks make your code cleaner and more readable. Prefer functional components over class components.
Example:
// β Class component
class Counter extends React.Component {
state = { count: 0 };
render() {
return (
<button onClick={() => this.setState({ count: this.state.count + 1 })}>
Count: {this.state.count}
</button>
);
}
}
// β
Functional component with Hook
function Counter() {
const [count, setCount] = React.useState(0);
return <button onClick={() => setCount(count + 1)}>Count: {count}</button>;
}
β 3οΈβ£ Use Meaningful & Consistent Naming
π Tip: Name components, props, and files clearly. Consistency avoids confusion.
Example:
- β
UserProfile.js
forUserProfile
component. - β
handleClick
instead of vagueonClickHandler1
.
β 4οΈβ£ Use PropTypes or TypeScript
π Why: Catch bugs early by validating props or using static types.
Example (with PropTypes):
import PropTypes from 'prop-types';
function Greeting({ name }) {
return <h1>Hello, {name}!</h1>;
}
Greeting.propTypes = {
name: PropTypes.string.isRequired,
};
Or use TypeScript for even stronger type safety:
type GreetingProps = {
name: string;
};
function Greeting({ name }: GreetingProps) {
return <h1>Hello, {name}!</h1>;
}
β 5οΈβ£ Use Destructuring for Props
π Why: Cleaner and easier to read.
Example:
// β Less readable
function Greeting(props) {
return <h1>Hello, {props.name}!</h1>;
}
// β
Destructuring
function Greeting({ name }) {
return <h1>Hello, {name}!</h1>;
}
β 6οΈβ£ Extract Reusable Logic with Custom Hooks
π Why: Donβt repeat yourself. Extract repeated logic into custom hooks.
Example:
// Custom Hook
function useWindowWidth() {
const [width, setWidth] = React.useState(window.innerWidth);
React.useEffect(() => {
const handleResize = () => setWidth(window.innerWidth);
window.addEventListener('resize', handleResize);
return () => window.removeEventListener('resize', handleResize);
}, []);
return width;
}
// Usage
function App() {
const width = useWindowWidth();
return <p>Window width: {width}px</p>;
}
β
7οΈβ£ Optimize Performance with React.memo
& useCallback
π Why: Prevent unnecessary re-renders.
Example:
const Button = React.memo(({ onClick, children }) => {
console.log('Rendering Button');
return <button onClick={onClick}>{children}</button>;
});
function App() {
const [count, setCount] = React.useState(0);
const handleClick = React.useCallback(() => {
console.log('Clicked!');
}, []);
return (
<div>
<Button onClick={handleClick}>Click me</Button>
<p>Count: {count}</p>
<button onClick={() => setCount(count + 1)}>Increment</button>
</div>
);
}
β 8οΈβ£ Always Clean Up Side Effects
π Why: Avoid memory leaks and unwanted behavior.
Example:
React.useEffect(() => {
const timer = setInterval(() => console.log('Tick'), 1000);
return () => {
clearInterval(timer); // β
Clean up
};
}, []);
β 9οΈβ£ Use Keys in Lists Correctly
π Why: Helps React track element changes.
Example:
// β
Correct: use unique & stable key
items.map(item => <li key={item.id}>{item.name}</li>)
// β Bad: avoid index as key if list can change
items.map((item, index) => <li key={index}>{item.name}</li>)
π BONUS PRINCIPLES π
β
Use Error Boundaries: Wrap critical parts to catch unexpected crashes.
β
Write Unit & Integration Tests: Use tools like Jest & React Testing Library.
β
Follow Folder Structure: Organize files by feature, not type.
β
Lint & Format: Use ESLint and Prettier for clean, consistent code.
β
Lazy Load & Code Split: Use React.lazy
& Suspense
to boost load times.
π Wrap Up
Following these best practices will help you write clean, maintainable, and robust React apps π. Keep learning, refactor ruthlessly, and donβt forget: clean code = happy future you!
π‘ Whatβs your favorite React best practice? Drop a comment and share it with the community!
π Happy Coding! π¨βπ»β¨
© Lakhveer Singh Rajput - Blogs. All Rights Reserved.