Boost Your React Skills with These 12 Best Practices .
1 Use Ternary Operator for Conditional Rendering:
import React from 'react';
const MyComponent = ({ isLoggedIn }) => {
return (
<div>
{isLoggedIn ? <p>Welcome, User!</p> : <p>Please login.</p>}
</div>
);
};
export default MyComponent;
2 Use JSX Spread Attributes for Props:
Using spread attributes is generally preferred as it makes the code cleaner and more maintainable, but it's essential to ensure that only necessary props are passed down to avoid unnecessary re-renders or potential bugs.
Example without spread attributes:
import React from 'react';
const MyComponentWithoutSpread = (props) => {
return <ChildComponent prop1={props.prop1} prop2={props.prop2} />;
};
export default MyComponentWithoutSpread;
Example with spread attributes:
import React from 'react';
const MyComponentWithSpread = (props) => {
return <ChildComponent {...props} />;
};
export default MyComponentWithSpread;
3 Use Fragment to Return Multiple Elements:
When returning multiple elements, use Fragment or shorthand syntax (<>...</>
).
import React from 'react';
const MyComponent = () => {
return (
<>
<h1>Title</h1>
<p>Content</p>
</>
);
};
export default MyComponent;
4 Keep Component State Local:
Keeping component state local ensures that each component manages its own state independently for better encapsulation and easier maintenance.
import React, { useState } from 'react';
const Parent = () => {
return (
<div>
<Child />
<Child />
</div>
);
};
const Child = () => {
const [count, setCount] = useState(0);
return (
<div>
<p>{count}</p>
<button onClick={() => setCount(count + 1)}>Increment</button>
</div>
);
};
export default Parent;
5 Use Memoization for Performance Optimization:
Memoization optimizes performance by caching expensive function results, reducing unnecessary recalculations and rendering in components for faster applications.
import React, { useMemo } from 'react';
const ExpensiveComponent = ({ num }) => {
const computedValue = useMemo(() => {
// Expensive computation
return num * 2;
}, [num]);
return <div>{computedValue}</div>;
};
export default React.memo(ExpensiveComponent);
6 Use Custom Hooks to Encapsulate Logic:
Using custom hooks in React encapsulates and reuses stateful logic across components, improving code reuse, organization, testing, and readability, making it a best practice for maintainable and clean code.
import { useState, useEffect } from 'react';
const useFetchData = (url) => {
const [data, setData] = useState(null);
const [loading, setLoading] = useState(true);
useEffect(() => {
fetch(url)
.then((response) => response.json())
.then((data) => {
setData(data);
setLoading(false);
});
}, [url]);
return { data, loading };
};
const DataDisplay = ({ url }) => {
const { data, loading } = useFetchData(url);
if (loading) return <p>Loading...</p>;
return <pre>{JSON.stringify(data, null, 2)}</pre>;
};
export default DataDisplay;
7 Avoid Inline Functions in JSX:
Avoid inline functions in JSX because they create new function instances on every render, which can hurt performance. Instead, define functions outside JSX to improve efficiency and prevent unnecessary re-renders.
const Button = ({ onClick }) => (
<button onClick={onClick}>Click me</button>
);
const App = () => {
const handleClick = () => {
console.log('Button clicked');
};
return <Button onClick={handleClick} />;
};
export default App;
8 Passing Default Props:
Passing default props ensures that your component has a fallback value if a prop is not provided. This enhances component reliability by preventing errors due to missing props and simplifies the component logic by reducing the need for explicit checks or conditional rendering within the component itself.
function Avatar({ person, size = 100 }) {
// ...
}
9 Use Component Composition:
Component composition in React means building complex components by combining simpler, reusable components for better maintainability and readability.
const Header = ({ title }) => <h1>{title}</h1>;
const Content = ({ children }) => <div>{children}</div>;
const App = () => (
<div>
<Header title="Welcome to My App" />
<Content>
<p>This is the content of the app.</p>
</Content>
</div>
);
export default App;
10 Use Cleanup Function in useEffect:
Cleanup function in useEffect ensures proper resource cleanup, preventing memory leaks and maintaining component cleanliness.
import React, { useState, useEffect } from 'react';
const Timer = () => {
const [count, setCount] = useState(0);
useEffect(() => {
const interval = setInterval(() => {
setCount(count => count + 1);
}, 1000);
// Cleanup function
return () => clearInterval(interval);
}, []); // Empty dependency array for componentDidMount behavior
return <div>Timer: {count}</div>;
};
export default Timer;
11 Use Error Boundary:
Using error boundaries helps to catch and handle errors in React components, providing better user experience, preventing crashes, and improving application robustness, making it a best practice for error management.
import React, { useState, useEffect } from 'react';
const ErrorFallback = () => (
<div>
<h2>Something went wrong!</h2>
<p>Please try again later.</p>
</div>
);
const ErrorBoundary = ({ children }) => {
const [hasError, setHasError] = useState(false);
useEffect(() => {
const handleError = (error, errorInfo) => {
console.error('Error caught by Error Boundary:', error, errorInfo);
setHasError(true);
};
// Return
12 Lazy Load Components
Lazy loading components helps to improve the performance of your React application by loading components only when they are needed. This can reduce the initial load time of your application.
import React, { Suspense, lazy } from 'react';
const LazyComponent = lazy(() => import('./LazyComponent'));
const App = () => {
return (
<div>
<h1>My App</h1>
<Suspense fallback={<div>Loading...</div>}>
<LazyComponent />
</Suspense>
</div>
);
};
export default App;
Top comments (0)