So, I have coded in Plain JS and then I thought to study the react since it is literally been so popular that next second child of the family knows this name "React".
and honestly in starting it looked simple , easy , and less effortive then writing whole HTML and then CSS for that but in react you can actuall use Tailwind makes it simple!.
Like in start we study about the components creating small , small element and then using them as a variable type.
also we use useState the first ever hook in react. so and on then learn about props passing etc etc.
but now, comes the real game-
There are more to do and learn in react.
When I first started using React, the word hooks used to confuse me. Like why we need it ? what does they do
They sounded fancy, magical, and way more complicated than they actually are. Especially useCallback, useEffect, and useRef — they felt like secret tools only React wizards understood.And you would not believe how many of YouTube vedios I have watched hindi or English!! but then
I built a small Password Generator project, things finally clicked.
In this post, I'll share how I went from scratching my head to finally "getting it," and how these hooks make our lives so much easier compared to plain JavaScript. Don't worry, I'll keep the vibe light, a little humorous, and human — because let's be honest, JavaScript already gives us enough headaches!
The Vanilla JavaScript Struggle
In vanilla JS, if you want to:
- React to something changing, you'd probably add a bunch of eventListeners.
- Cache a function to avoid re-creating it, you'd manually control variables and scope.
- Hold a reference to an element, you'd mess around with document.querySelector.
This works, but it's messy, repetitive, and doesn't scale well when your app grows.
Enter React Hooks.
1. useCallback – Keep That Function in Memory
Think of useCallback like telling React:
"Hey React, don't create this function again and again unless one of these things changes."
It's basically a function memoizer.
Syntax:
const cachedFunction = useCallback(() => {
// your function logic
}, [dependencies]);
Dependencies are the things that decide when your function should be re-created.
In My Password Generator:
When I play around with password length, toggle numbers, or characters, I want the password generator function to update only if those change.
const passwordGenerator = useCallback(() => {
let pass = "";
let str = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
if (numberAllowed) str += "0123456789";
if (charAllowed) str += "!@#$%^&*(){}[]<>?/";
for (let i = 1; i <= length; i++) {
const char = Math.floor(Math.random() * str.length + 1);
pass += str.charAt(char);
}
setPassword(pass);
}, [length, numberAllowed, charAllowed, setPassword]);
This way, React doesn't waste time recreating the function when nothing relevant has changed.
2. useEffect – Run Side Effects When Something Changes {Run the method with external change or clicks}
If useCallback is about saving a function, useEffect is about running a function whenever some state/props change.
It's like saying:
"Whenever these things change, please run this function AGAAINNN."
Syntax:
useEffect(() => {
// do something when dependencies change
}, [dependencies]);
In My Project:
Whenever length, numberAllowed, or charAllowed change, I want to regenerate the password:
useEffect(() => {
passwordGenerator();
}, [length, numberAllowed, charAllowed, passwordGenerator]);
So if I move the slider for length or toggle checkboxes, the password updates automatically. No manual button smashing needed.
3. useRef – Hold a Reference (Without Re-rendering)
This one is like React's way of saying:
"Here's a sticky note. Put it on any element and I'll keep track of it for you."
Unlike state, changing a ref doesn't cause re-renders.
Syntax:
const myRef = useRef(null);
<input ref={myRef} />
In My Project:
I used useRef to hold the reference of the password field so that when I click the Copy button, I can copy the text directly.
const passwordRef = useRef(null);
const copyPasswordToClipboard = useCallback(() => {
passwordRef.current?.select();
window.navigator.clipboard.writeText(password);
}, [password]);
Now, the copy button works smoothly, and I don't have to manually query the DOM.
Final Thoughts
When I first read about these hooks, I thought: "Why can't I just write vanilla JS and be done with it?" But after using them in this project, I realized:
- useCallback saves us from unnecessary re-creations of functions.
- useEffect lets us run code automatically when dependencies change.
- useRef helps us interact with DOM elements without re-renders.
Together, they made my little password generator smooth, optimized, and React-y. 🚀
So next time hooks confuse you, just remember — they're here to make your life easier, not harder. And if you're ever stuck, try building something small and fun (like a password generator). It'll all make sense eventually.
✨ That's it for this one! I'd love to know: Which React hook gave you the biggest headache when you first started?
Top comments (0)