ReactJS Tips and Tricks with Examples
Learn essential ReactJS tips and tricks with simple English explanations, bad code vs good code examples, performance optimization, and best practices.
2026-08-27 · 9 min read
ReactJS Tips & Tricks — Best Practice with Examples
Hello friend! Today we share best ReactJS tips and tricks. These tips help you write clean code, avoid common bug, and make React app run faster!
If you are new to ReactJS, read our step-by-step previous lessons first:
- ⚛️ ReactJS Get Started Guide
- 🧩 Functional Component vs Class Component
- 🔄 ReactJS State Management (useState)
We explain in simple way with Bad Code ❌ vs Good Code ✅. Easy to understand!
1. Use Functional Component (Not Class Component)
Modern React use Functional Component with Hooks. Do not use old Class Component anymore. It is easier to read and write less code!
❌ Bad (Old Class Component):
class Welcome extends React.Component {
render() {
return <h1>Hello, {this.props.name}!</h1>;
}
}
✅ Good (Functional Component):
function Welcome({ name }) {
return <h1>Hello, {name}!</h1>;
}
💡 Tip: Want to learn more about components and props? Read our full guide: → Functional and Class Component with Props in ReactJS
2. Functional State Update — setCount(prev => prev + 1)
When new state depend on previous state, always use functional update. If you pass value directly, it can have bug when state update multiple times quickly!
❌ Bad:
const handleClick = () => {
setCount(count + 1);
setCount(count + 1); // ⚠️ Bug! Count only increase by 1, not 2!
};
✅ Good:
const handleClick = () => {
setCount(prev => prev + 1);
setCount(prev => prev + 1); // ✅ Work correct! Count increase by 2!
};
💡 Tip: Want deep dive into state management? Check out: → ReactJS State Management with useState
3. Never Mutate State Directly
In React, state is immutable (do not change original object/array directly). Always make a new copy using spread operator (...)!
❌ Bad (Direct Mutation):
const [user, setUser] = useState({ name: 'Rean', age: 20 });
// ❌ React will NOT re-render because object reference not change!
user.age = 21;
setUser(user);
✅ Good (Spread Operator):
const [user, setUser] = useState({ name: 'Rean', age: 20 });
// ✅ Create new object copy — React re-render properly!
setUser({ ...user, age: 21 });
💡 Tip: For Array, use
[...items, newItem]to add, or.filter()to delete. Never use.push()or.splice()directly on state!
4. Always Use Unique key in .map() List
When render list with .map(), React need unique key prop to identify each item. Do not use array index i as key if list item order can change!
❌ Bad (Use Index as Key):
{users.map((user, index) => (
<li key={index}>{user.name}</li>
))}
✅ Good (Use Unique ID as Key):
{users.map(user => (
<li key={user.id}>{user.name}</li>
))}
⚠️ Warning: Using array index as key can cause wrong UI animation and form input bug when list item sorted or deleted!
5. Be Careful with && Conditional Rendering
Using && with numbers can print 0 on screen if number is 0!
❌ Bad:
const itemCount = 0;
return (
<div>
{/* ❌ This will print "0" on screen! Because 0 is falsy but React render 0! */}
{itemCount && <p>You have {itemCount} items</p>}
</div>
);
✅ Good:
const itemCount = 0;
return (
<div>
{/* ✅ Explicit check with > 0 or Ternary operator */}
{itemCount > 0 && <p>You have {itemCount} items</p>}
{/* Or ternary: */}
{itemCount > 0 ? <p>You have {itemCount} items</p> : null}
</div>
);
6. Cleanup useEffect Timers and Subscriptions
If you use setInterval, setTimeout, or add event listener inside useEffect, always return cleanup function. Otherwise you get memory leak!
❌ Bad (No Cleanup):
useEffect(() => {
const timer = setInterval(() => {
console.log('Tick');
}, 1000);
// ❌ Memory leak! Timer keep running even when component unmounted!
}, []);
✅ Good (With Cleanup):
useEffect(() => {
const timer = setInterval(() => {
console.log('Tick');
}, 1000);
// ✅ Clean up timer when component unmount!
return () => clearInterval(timer);
}, []);
7. Custom Hooks — Reuse Your Logic
If you write same useEffect or state logic in multiple components, extract it into a Custom Hook! Custom Hook name must start with use.
✅ Example (Custom Hook useFetch):
// hooks/useFetch.js
function useFetch(url) {
const [data, setData] = useState(null);
const [loading, setLoading] = useState(true);
useEffect(() => {
fetch(url)
.then(res => res.json())
.then(data => {
setData(data);
setLoading(false);
});
}, [url]);
return { data, loading };
}
// Use inside any component:
function UserList() {
const { data, loading } = useFetch('/api/users');
if (loading) return <p>Loading...</p>;
return <div>{/* render data */}</div>;
}
💡 Tip: Custom Hooks make your UI component very clean and short!
8. Handle Loading & Error States in API Call
Always handle Loading, Error, and Data states when fetch data from API. Don't leave user on blank screen!
✅ Good Practice:
function StudentList() {
const [students, setStudents] = useState([]);
const [loading, setLoading] = useState(true);
const [error, setError] = useState(null);
useEffect(() => {
fetch('https://api.example.com/students')
.then(res => {
if (!res.ok) throw new Error('Failed to fetch data');
return res.json();
})
.then(data => {
setStudents(data);
setLoading(false);
})
.catch(err => {
setError(err.message);
setLoading(false);
});
}, []);
if (loading) return <div>⏳ Loading students...</div>;
if (error) return <div>❌ Error: {error}</div>;
return (
<ul>
{students.map(s => <li key={s.id}>{s.name}</li>)}
</ul>
);
}
9. Destructure Props for Cleaner Code
Pass props directly and destructure in component parameter. Don't repeat props.name, props.age, props.email everywhere!
❌ Bad:
function UserCard(props) {
return (
<div>
<h3>{props.name}</h3>
<p>{props.email}</p>
<p>{props.role}</p>
</div>
);
}
✅ Good:
function UserCard({ name, email, role = 'User' }) {
return (
<div>
<h3>{name}</h3>
<p>{email}</p>
<p>{role}</p>
</div>
);
}
💡 Tip: You can also set default value directly:
role = 'User'.
10. Use Fragment <> to Avoid Extra <div>
React component must return single parent element. Instead of adding extra <div> wrappers that mess up CSS flexbox/grid, use React Fragment <> ... </>!
❌ Bad (Extra unnecessary DOM node):
return (
<div className="wrapper">
<Header />
<MainContent />
</div>
);
✅ Good (Clean DOM):
return (
<>
<Header />
<MainContent />
</>
);
💡 Tip: Read our detailed guide on Fragment: → ReactJS Fragment Explained with Code Examples
11. Keep State Close to Where it is Used
Don't put all state in root component (App.jsx) if only small child component need it!
❌ Bad: Putting search input state in App component when only SearchBar component use it. ✅ Good: Put search input state inside SearchBar component directly.
💡 Tip: Lift state up to parent ONLY when multiple sibling components need to share same state!
12. Don't Store Derived State
If value can be calculated from existing state or props, do not store it in a new state!
❌ Bad:
const [firstName, setFirstName] = useState('Rean');
const [lastName, setLastName] = useState('Code');
const [fullName, setFullName] = useState('Rean Code'); // ❌ Unnecessary state!
✅ Good:
const [firstName, setFirstName] = useState('Rean');
const [lastName, setLastName] = useState('Code');
// ✅ Calculate directly! Automatically update when firstName or lastName change!
const fullName = `${firstName} ${lastName}`;
13. Controlled Input for Forms
For form inputs in React, use value and onChange to make input state controlled by React.
✅ Good Example:
function LoginForm() {
const [email, setEmail] = useState('');
const handleSubmit = (e) => {
e.preventDefault(); // Stop browser reload!
console.log('Submitting email:', email);
};
return (
<form onSubmit={handleSubmit}>
<input
type="email"
value={email}
onChange={(e) => setEmail(e.target.value)}
placeholder="Enter email"
/>
<button type="submit">Login</button>
</form>
);
}
💡 Tip: Learn more about forms and event handling: → Basic Event Handling with Form in ReactJS
14. Never Put Secret API Keys in Frontend Code
React code runs inside user browser. Anyone can open Browser DevTools (F12) and see your API secret keys!
❌ Bad:
const STRIPE_SECRET_KEY = 'sk_test_123456789'; // ❌ NEVER DO THIS!
✅ Good:
- Use public key only on frontend (
NEXT_PUBLIC_...orVITE_...). - Put secret API keys on backend server (Node.js, Next.js API Route, Laravel, etc.)!
15. Optimize Only When Needed (useMemo & useCallback)
Do NOT wrap every function with useCallback or every value with useMemo. Overusing them makes code harder to read and slows down memory performance!
💡 Rule of Thumb:
- Use
useMemoONLY for expensive calculation (like sorting 10,000 items).- Use
useCallbackONLY when passing function to child component wrapped withReact.memo().- First write simple clean code. Optimize only when you notice performance lag!
Summary — Quick Checklist
| Tip | Description | Benefit |
|---|---|---|
| 1. Functional Component | Use function + Hooks | Modern, clean code |
2. setCount(prev => prev + 1) | Functional state update | Avoid async state bug |
| 3. Immutable State | Use ...spread copy | Trigger proper re-render |
4. Unique key | Use user.id not index | Prevents list UI bugs |
5. Safe && | Use count > 0 && ... | Avoid printing 0 on screen |
6. Cleanup useEffect | Return () => clearInterval() | Avoid memory leak |
| 7. Custom Hooks | useFetch(), useAuth() | Reuse logic easily |
| 8. Loading & Error | Handle loading, error, data | Great UX for user |
| 9. Destructure Props | function({ name, age }) | Less repetitive code |
10. Fragment <> | Return <> ... </> | No useless <div> in DOM |
📚 Read Previous ReactJS Tutorials
If you want to learn more about ReactJS, check out all our previous step-by-step lessons:
- ⚛️ Lesson 1 — ReactJS Get Started Guide
- 🧩 Lesson 2 — Functional & Class Component with Props
- 📝 Lesson 3 — Basic Event Handling with Form
- 📦 Lesson 4 — ReactJS Fragment Explained
- 🔄 Lesson 5 — State Management with useState
- 🚦 Lesson 6 — Basic Routing with React Router
Happy coding with ReactJS! 🎉