I used to think custom hooks were just… fancy function wrappers 🤷♂️ My first reaction was: “Wait… we’re just grouping useState and useEffect in a separate file and calling it a hook?” 🤔 And yeah - technically, that’s true. But here’s what I completely missed 👇 Not every grouped logic needs to be a custom hook. I started creating: -- useToggle, useCounter, useFormInput For. Everything. 😅 My hooks folder was growing faster than my actual components 📁📈 That’s when I realized something important: The real power of custom hooks isn’t abstraction itself - it’s when and why you abstract. Here’s my rule now: ✅ Is this logic complex AND reused? → Custom hook ✅ Is it shared across multiple components? → Custom hook ❌ Is it just 3 lines of state? → Keep it in the component 🚨 Am I building this “just in case”? → Stop right there Abstraction should reduce mental load 🧠 Not increase file count 📁 Clean code isn’t about how many hooks you can create. It’s about how easily someone can understand your component at 11:30 PM during a production bug call 🔥 Less clever. More clear. #React #JavaScript #WebDev #CleanCode
Custom Hooks: When to Abstract and When to Keep It Simple
More Relevant Posts
-
𝐀𝐫𝐞 𝐲𝐨𝐮 𝐬𝐭𝐢𝐥𝐥 𝐥𝐞𝐭𝐭𝐢𝐧𝐠 `useEffect` 𝐫𝐞-𝐫𝐮𝐧 𝐲𝐨𝐮𝐫 𝐞𝐱𝐩𝐞𝐧𝐬𝐢𝐯𝐞 𝐥𝐨𝐠𝐢𝐜 𝐟𝐨𝐫 𝐧𝐨 𝐠𝐨𝐨𝐝 𝐫𝐞𝐚𝐬𝐨𝐧? 🤯 It’s a common scenario: you have a `useEffect` that sets up a subscription or an interval, and you really only want it to run once on mount and clean up on unmount. So you put an empty dependency array `[]`. But what happens when you need a reference to a mutable value (like a prop or state) inside that effect, but you don't want changes to that value to re-trigger the effect? If you add it to the dependency array, it re-runs. If you omit it, you risk stale closures. Enter `useRef` as your stable escape hatch! Instead of: ```typescript useEffect(() => { const handler = () => console.log(someProp); // someProp is stale window.addEventListener('scroll', handler); return () => window.removeEventListener('scroll', handler); }, []); // Empty deps, but `someProp` is captured at mount ``` Try this pattern: ```typescript const latestSomeProp = useRef(someProp); useEffect(() => { latestSomeProp.current = someProp; // Update the ref on every render const handler = () => console.log(latestSomeProp.current); // Always fresh! window.addEventListener('scroll', handler); return () => window.removeEventListener('scroll', handler); }, []); // Effect itself only runs once ``` This way, your `useEffect` only runs once for setup/teardown, but `latestSomeProp.current` always holds the most up-to-date value. It’s perfect for ensuring cleanup functions always operate on the current state or props, without re-triggering the effect. It's a subtle but powerful pattern for optimizing performance and avoiding tricky bugs in React. What other `useEffect` patterns have saved you from debugging hell? Share your tips! #React #FrontendDevelopment #JavaScript #WebDev #Performance
To view or add a comment, sign in
-
💡 𝗝𝗮𝘃𝗮𝗦𝗰𝗿𝗶𝗽𝘁’𝘀 𝗛𝗶𝗱𝗱𝗲𝗻 𝗚𝗲𝗺: 𝗧𝗵𝗲 𝗖𝗼𝗺𝗺𝗮 𝗢𝗽𝗲𝗿𝗮𝘁𝗼𝗿 (,) Most developers go years without noticing this small but powerful operator in JavaScript. 👉 The 𝗰𝗼𝗺𝗺𝗮 𝗼𝗽𝗲𝗿𝗮𝘁𝗼𝗿 allows you to evaluate multiple expressions in a single line — but it always returns the value of the 𝗹𝗮𝘀𝘁 𝗲𝘅𝗽𝗿𝗲𝘀𝘀𝗶𝗼𝗻. 🔍 𝗘𝘅𝗮𝗺𝗽𝗹𝗲 let x = 10; let y = 40; x = (y += 20, y); console.log(x); // 60 ✔️ y += 20 runs first → y becomes 60 ✔️ The last expression y is returned → x becomes 60 🧠 Where is it useful? ✅ Compact logic in for loops for (let i = 0, j = 5; i < j; i++, j--) { console.log(i, j); } ✅ Evaluating multiple expressions in one statement ⚠️ Use sparingly — readability matters more than cleverness. 🚨 𝗣𝗿𝗼 𝗧𝗶𝗽 If your code makes teammates pause and squint 🤨 — it’s probably better written in a clearer way. 𝗖𝗹𝗲𝗮𝗻 𝗰𝗼𝗱𝗲 > 𝗰𝗹𝗲𝘃𝗲𝗿 𝗰𝗼𝗱𝗲. Have you ever used the comma operator in production, or is this your first time seeing it? 👇 #JavaScript #WebDevelopment #CleanCode #Frontend #ProgrammingTips
To view or add a comment, sign in
-
useState and useEffect are just the beginning. React gives you more hooks to write faster, cleaner, smarter code. Here are the ones that level you up: 📌 useRef — store values silently (no re-render!) + access DOM elements directly 🧠 useMemo — cache expensive calculations, only recalculate when inputs change 🔒 useCallback — cache functions to prevent unnecessary child re-renders 🛠️ Custom Hooks — extract reusable logic into "use" functions (write once, use everywhere) ⚠️ Rules of Hooks — never call inside if/else or loops (React tracks them by order!) 📊 Quick reference — which hook re-renders? Only useState. The golden rule: start with useState + useEffect. Add the rest only when you actually need them. Save this cheat sheet. You'll reference it more than you think. ♻️ Repost to help someone level up their React skills. #React #Hooks #useRef #useMemo #useCallback #JavaScript #WebDev
To view or add a comment, sign in
-
-
Stop Shipping "Ghost Code" 👻 – Meet Knip! Is your codebase becoming a graveyard for unused files and "just in case" exports? 🏚️ As projects grow, we often leave behind dead code: exports that aren't imported anywhere, dependencies that are no longer used, and files that are just taking up space. This doesn't just look messy— hurts your bundle size, slows down CI/CD pipelines, and confuses new developers. Enter Knip ✂️ – the ultimate "dust-buster" for your JavaScript and TypeScript projects. What does Knip actually find? ✅ Unused Files: Clean up those orphaned .ts or .js files. ✅ Unused Dependencies: Identify packages in package.json that are just sitting there. ✅ Unused Exports: Find functions/types you exported but never actually used. ✅ Duplicate Exports: Spot redundant code before it becomes a headache. Why I’m a fan: Unlike many other tools, Knip is incredibly smart. It understands monorepos, supports major frameworks (React, Next.js, Svelte, etc.), and integrates seamlessly with your existing tools like ESLint and Prettier. How to get started in 10 seconds: To install: `npm install knip` To check: `npx knip` That’s it. No complex configuration is needed to get your first report. A clean codebase isn’t just about aesthetics; it’s about performance and maintainability. If you haven't audited your project recently, give Knip a try today! Have you used Knip before? What’s the biggest "dead code" monster you’ve uncovered? Let me know in the comments! 👇 #WebDevelopment #TypeScript #JavaScript #CleanCode #OpenSource #SoftwareEngineering #WebPerf #Knip Thanks to Lars Kappert
To view or add a comment, sign in
-
If JavaScript is single‑threaded, how does it still handle Promises, API calls, and Timers without blocking the application? The answer lies in the Event Loop. Let’s take a simple example: What would be the output of the below code? console.log("Start"); setTimeout(() => { console.log("Timeout"); }, 0); Promise.resolve().then(() => { console.log("Promise"); }); console.log("End"); Some may guess the output to be: Start End Timeout Promise But the actual output is: Start End Promise Timeout So what is happening behind the scenes? 🔵 Synchronous Code Being synchronous, console.log("Start") and console.log("End") run immediately in the Call Stack. 🔵 Promises Resolved promises go to the Microtask Queue which is executed next. 🔵 setTimeout Timer callbacks go to the Macrotask Queue, even if the delay is '0ms', which is executed last. ✅ Simple flow to remember Synchronous Code → Promises (Microtasks) → setTimeout (Macrotasks) So even with 0 delay, Promises will always execute before setTimeout. Understanding this small but important detail will help developers debug async behavior and write more predictable JavaScript applications. #javascript #webdevelopment #eventloop #asyncprogramming
To view or add a comment, sign in
-
🚨 Most developers get this wrong about the JavaScript Event Loop What do you think this prints? 👇 console.log("Start"); setTimeout(() => console.log("Timeout"), 0); console.log("End"); Many people expect: ❌ Start ❌ Timeout ❌ End But the actual output is: ✅ Start ✅ End ✅ Timeout Why? 🤔 Because JavaScript is single-threaded and uses the Event Loop to handle async tasks. Here’s what really happens behind the scenes: 1️⃣ console.log("Start") → runs immediately in the Call Stack 2️⃣ setTimeout() → moves to Web APIs 3️⃣ console.log("End") → runs next (still synchronous) 4️⃣ Timer finishes → callback goes to Callback Queue 5️⃣ Event Loop pushes it to the Call Stack when it's empty 6️⃣ console.log("Timeout") finally runs 💡 Even setTimeout(..., 0) is never truly instant. If you understand this concept, debugging async JavaScript becomes 10x easier. 💬 Comment “EVENT LOOP” if you want a deeper breakdown with Promises & Microtasks. #javascript #webdevelopment #nodejs #frontend #backend #programming #eventloop #coding
To view or add a comment, sign in
-
-
⚡ A Common JavaScript Misconception About the Event Loop Many developers think: "setTimeout(fn, 0) runs immediately." That’s incorrect. Even with 0 milliseconds, the callback still goes through the Event Loop cycle. Example: console.log("A"); setTimeout(() => console.log("B"), 0); Promise.resolve().then(() => console.log("C")); console.log("D"); Output: A D C B Why? Because JavaScript has two queues: 🔹 Microtask Queue → Promises, MutationObserver 🔹 Callback Queue → setTimeout, setInterval The Event Loop always processes microtasks first. Understanding this difference is critical when debugging async behavior in real applications. Master the Event Loop → Master asynchronous JavaScript. #javascript #asyncjavascript #webdevelopment #frontend #mernstack
To view or add a comment, sign in
-
-
Day 3/30 JavaScript Challenge: Giving the Browser a Voice! 🗣️ I just finished Day 3 of my 30-day JavaScript series, and today was all about the Web Speech API. I built a Text-to-Voice application that turns any typed input into spoken words instantly! It’s amazing how much functionality is built right into the browser without needing any external libraries or APIs. Key Learnings Today: => Using SpeechSynthesisUtterance to handle voice properties. => Manipulating the DOM to capture user input. => Creating a clean, responsive UI with CSS gradients and transitions. Live Demo: https://lnkd.in/decEYAvw Onward to Day 4! ⚡ #JavaScript #WebDevelopment #CodingChallenge #100DaysOfCode #Frontend #LearningToCode
To view or add a comment, sign in
-
⚠️ One tricky thing in React that confused me at first: useEffect dependencies At first, I thought useEffect just runs magically. But the truth is very simple 👇 🧠 Think of useEffect like this: “React, run this code after render, and re‑run it only when I tell you to.” That “telling” happens through the dependency array. ✅ Examples (super simple) useEffect(() => { console.log("Runs once"); }, []); ➡️ Runs only when component mounts but for the below case useEffect(() => { console.log("Runs when count changes"); }, [count]); ➡️ Runs every time count changes 🚨 The tricky part If you use a variable inside useEffect but forget to add it as a dependency, React will use an old value (stale data). 🧠 Rule to remember: If you use it inside useEffect, it should be in the dependency array. Once I understood this, useEffect stopped feeling scary 😊 Just logic + clarity. #React #JavaScript #Hooks #useEffect #Frontend #LearningInPublic
To view or add a comment, sign in
-
𝗪𝗵𝘆 𝘁𝘆𝗽𝗲𝗼𝗳 𝗻𝘂𝗹𝗹 𝗶𝘀 "𝗼𝗯𝗷𝗲𝗰𝘁" — 𝗧𝗵𝗲 𝟯𝟬-𝗬𝗲𝗮𝗿 𝗕𝘂𝗴 𝗧𝗵𝗮𝘁 𝗪𝗼𝗻’𝘁 𝗗𝗶𝗲 🐛 If you’ve ever debugged JavaScript and seen typeof null === 'object', you probably thought your code was broken. It’s not you. It’s one of the oldest "mistakes" in web history. Here’s the deep dive into why this quirk exists and why we’re stuck with it forever: 𝟭. 𝗧𝗵𝗲 "𝟭𝟬-𝗗𝗮𝘆" 𝗢𝗿𝗶𝗴𝗶𝗻 𝗦𝘁𝗼𝗿𝘆 ⏱️ In 1995, Brendan Eich created JavaScript in just 10 days. In that rush, the engine's internal structure used a "type tag" system to identify data. ● 𝗢𝗯𝗷𝗲𝗰𝘁𝘀 were assigned the tag 000. ● 𝗻𝘂𝗹𝗹, representing a null pointer, was represented as all zeros (0x00). Because the engine checked for the 000 tag to identify objects, and null consists entirely of zero bits, the typeof operator incorrectly flagged it as an object. 𝟮. 𝗧𝗵𝗲 𝗔𝘁𝘁𝗲𝗺𝗽𝘁𝗲𝗱 𝗙𝗶𝘅 🛠️ There was actually a proposal to "fix" this in ECMAScript 6 so that typeof null would return 'null'. So, why didn't it happen? 𝟯. 𝗧𝗵𝗲 "𝗗𝗼𝗻'𝘁 𝗕𝗿𝗲𝗮𝗸 𝘁𝗵𝗲 𝗜𝗻𝘁𝗲𝗿𝗻𝗲𝘁" 𝗥𝘂𝗹𝗲 🌐 Backward compatibility is the golden rule of the web. Millions of websites and legacy libraries rely on this specific bug for their logic. Changing it now would "break the internet," causing countless sites to crash. As Brendan Eich himself noted: “𝘐𝘵’𝘴 𝘵𝘰𝘰 𝘭𝘢𝘵𝘦 𝘵𝘰 𝘧𝘪𝘹.” 𝗧𝗵𝗲 𝗧𝗮𝗸𝗲𝗮𝘄𝗮𝘆 𝗳𝗼𝗿 𝗗𝗲𝘃𝘀: ✅ Never use typeof to check for null. ✅ Always use strict equality: myVar === null. ✅ Pro Tip: To check if something is actually a valid object, use: myVar !== null && typeof myVar === 'object'. JavaScript isn’t perfect, but its quirks are what make its history so fascinating. What’s your "favorite" JavaScript bug or quirk? Let’s discuss in the comments! 👇 #JavaScript #WebDevelopment #Programming #SoftwareEngineering #CodingLife #TechHistory #Frontend
To view or add a comment, sign in
-
Explore related topics
- How to Organize Code to Reduce Cognitive Load
- How Developers Use Composition in Programming
- Building Clean Code Habits for Developers
- Coding Best Practices to Reduce Developer Mistakes
- Intuitive Coding Strategies for Developers
- GitHub Code Review Workflow Best Practices
- Choosing DRY vs. Custom Code in Software Development
- How to Add Code Cleanup to Development Workflow
- How to Create Purposeful Codebases
Explore content categories
- Career
- Productivity
- Finance
- Soft Skills & Emotional Intelligence
- Project Management
- Education
- Technology
- Leadership
- Ecommerce
- User Experience
- Recruitment & HR
- Customer Experience
- Real Estate
- Marketing
- Sales
- Retail & Merchandising
- Science
- Supply Chain Management
- Future Of Work
- Consulting
- Writing
- Economics
- Artificial Intelligence
- Employee Experience
- Workplace Trends
- Fundraising
- Networking
- Corporate Social Responsibility
- Negotiation
- Communication
- Engineering
- Hospitality & Tourism
- Business Strategy
- Change Management
- Organizational Culture
- Design
- Innovation
- Event Planning
- Training & Development