DEV Community

Solomon Isu
Solomon Isu

Posted on

I Built a Job Tracker and These Bugs Nearly Finished Me — Advice Welcome 🐛

Hey Dev.to community 👋

I'm a growing developer and I just finished building my first
real full-stack project — a Job Application Tracker built with
Next.js, TypeScript, MongoDB and DnD Kit.

I'm writing this partly to document what I faced, partly to
laugh about it, and mostly to ask for advice from more experienced
developers on how to handle these situations better next time.


The Project

A Kanban-style job application tracker where you can:

  • Add, edit and delete job applications
  • Drag and drop between columns
  • Move jobs via dropdown menu
  • All updates reflect immediately without page refresh

Tech stack:

  • Next.js 16 (App Router)
  • TypeScript
  • MongoDB + Mongoose
  • Better Auth
  • DnD Kit
  • shadcn/ui + Tailwind CSS

The Bugs — A Sarcastic Love Letter 💌

1. The useEffect setState Anti-Pattern

I was calling setBoard and setColumns directly inside a useEffect.
React responded with a wall of red text about cascading re-renders.
Delightful.

The fix was simple — useState already handles initial values.
The useEffect was doing the same job twice.

👉 Advice needed: Is there a pattern you follow to know when
useEffect is actually necessary vs unnecessary?


2. TypeScript's Obsession With Types

initialBoard had 3 possible values (Board | null | undefined).
setBoard only accepted 2 (Board | null). TypeScript lost its mind.
I lost my mind. Eventually we came to an agreement.

The fix was using initialBoard?.columns in the if check which
gave TypeScript enough confidence to calm down.

👉 Advice needed: How do you handle these type narrowing situations
more elegantly in large codebases?


3. The UI That Refused To Update

Server actions were saving to the database perfectly. The UI
sat there staring at me like nothing happened.

Turns out telling the database something changed and telling
the UI something changed are two completely different conversations.
I had to build a full callback chain from useBoard all the way
down to each component.

👉 Advice needed: Is this callback chain pattern the right
approach or is there a cleaner way? Should I be using something
like Zustand or React Query instead?


4. revalidatePath — The Silent Callback Killer

Just when the callback chain was working — revalidatePath was
quietly running in the background wiping all callbacks out on
every action. onJobAdded is not a function it said.

Removing revalidatePath fixed it — but now I'm handling all
UI updates manually.

👉 Advice needed: What's the best practice here? revalidatePath
vs manual state updates? Or a combination of both?


5. "use cache" — The Freshness Illusion

Next.js was serving beautifully cached stale data on every refresh.
Move a job to a new column. Refresh. Gone. Back where it started.
Like it never happened.

Removing "use cache" fixed it immediately.

👉 Advice needed: How do you properly handle caching in Next.js
App Router without breaking real-time updates?


6. The DnD Hydration Mismatch

The crown jewel. DnD Kit generating DndDescribedBy-0 on the server
and DndDescribedBy-1 on the client. A difference of exactly ONE
number causing a wall of red hydration warnings on every single
page load.

Although purely cosmetic — it's a bloody pain in the ass.

The fix was the isMounted pattern — only rendering DndContext
on the client:

const [isMounted, setIsMounted] = useState(false);

useEffect(() => {
setIsMounted(true);
}, []);

if (!isMounted) return null;

👉 Advice needed: Is there a better way to handle DnD Kit
hydration issues in Next.js? Is this a known issue with a
planned fix?


What I Learned

Building a real project teaches you things no tutorial ever will.

  • React is opinionated. Respect it.
  • TypeScript is unforgiving. Respect it more.
  • Next.js caching will humble you.
  • Purely cosmetic bugs are still a bloody pain in the ass.
  • Debugging at 2am builds character apparently.

My Ask

I'm a growing developer and I'd love honest feedback from the
community:

  1. Are there better patterns for any of these solutions?
  2. What tools or libraries would have made this easier?
  3. What would YOU have done differently?

All advice welcome — roast me if you must. I can take it. 😂

GitHub: https://github.com/solodevx/venarium-job-application-tracker

Thanks for reading! 🚀

Top comments (0)