Common Gotchas
These are the most common mistakes in full-stack interviews. Know them by heart.
| Problem | Solution |
|---|---|
| CORS errors in console | Add CORSMiddleware to FastAPI (first thing!) |
| "use client" missing | Add it for any component with state/effects |
| Missing key prop warning | Always add key={uniqueId} in .map() |
| Form refreshes the page | Add e.preventDefault() in onSubmit |
| State not updating immediately | State updates are async — use functional updates |
| Infinite useEffect loop | Check your dependency array — don't include objects/arrays |
| Cannot read property of undefined | Add loading states, check data exists before accessing |
| API returns HTML instead of JSON | Check the URL — probably hitting wrong endpoint |
| Changes not persisting | Make sure you're calling db.commit() in FastAPI |
| WebSocket won't connect | Use ws:// not http://, check CORS |
Detailed Explanations
CORS Errors ("Access-Control-Allow-Origin")
This is the #1 issue in full-stack development. Your browser blocks requests from localhost:3000 to localhost:8000 unless the server explicitly allows it.
Fix: Add CORS middleware IMMEDIATELY after creating your FastAPI app.
1from fastapi.middleware.cors import CORSMiddleware23app = FastAPI()45# ADD THIS RIGHT AFTER CREATING THE APP6app.add_middleware(7 CORSMiddleware,8 allow_origins=["http://localhost:3000"],9 allow_credentials=True,10 allow_methods=["*"],11 allow_headers=["*"],12)
Missing 'use client' Directive
Next.js 13+ uses Server Components by default. If you try to use useState, useEffect, or onClick without marking the component as a client component, you'll get an error.
Fix: Add "use client" at the very top of the file (before imports).
1"use client" // Must be FIRST LINE23import { useState } from "react"45export default function MyComponent() {6 const [count, setCount] = useState(0)7 // ...8}
Form Refreshes the Page
By default, HTML forms submit and refresh the page. In a React app, you want to prevent this and handle submission with JavaScript.
Fix: Call e.preventDefault() at the start of your submit handler.
1const handleSubmit = async (e: React.FormEvent) => {2 e.preventDefault() // CRITICAL! Prevents page reload34 // Now handle the submission5 await fetch("/api/items", {6 method: "POST",7 body: JSON.stringify(data),8 })9}
Missing Key Prop in Lists
React needs a unique key prop for each item in a list to efficiently update the DOM. Missing keys cause warnings and can lead to bugs.
Fix: Always add key={item.id} when mapping over arrays.
1// WRONG - No key2{items.map((item) => (3 <div>{item.name}</div>4))}56// CORRECT - Has unique key7{items.map((item) => (8 <div key={item.id}>{item.name}</div>9))}1011// If no ID, use index (last resort)12{items.map((item, index) => (13 <div key={index}>{item.name}</div>14))}
State Not Updating Immediately
setState is asynchronous. If you log state right after setting it, you'll see the old value.
Fix: Use a useEffect to watch for changes, or use functional updates.
1// WRONG - count is still 0 after this2setCount(count + 1)3console.log(count) // Still 0!45// CORRECT - Use functional update for derived state6setCount(prev => prev + 1)78// CORRECT - Watch with useEffect9useEffect(() => {10 console.log("Count changed:", count)11}, [count])
Infinite useEffect Loop
If your useEffect runs infinitely, it's usually because you're including a dependency that changes on every render (like objects or arrays).
Fix: Only include primitive values in the dependency array, or use useMemo/useCallback.
1// WRONG - options object is recreated every render2const options = { limit: 10 }3useEffect(() => {4 fetchData(options)5}, [options]) // Infinite loop!67// CORRECT - Use primitive values8const limit = 109useEffect(() => {10 fetchData({ limit })11}, [limit])1213// CORRECT - Empty array for "run once"14useEffect(() => {15 fetchData()16}, [])
Debugging Checklist
When Something Isn't Working:
- 1Check the browser console for errors (F12 → Console)
- 2Check the network tab for failed requests (F12 → Network)
- 3Check the terminal running FastAPI for Python errors
- 4Verify both servers are running (frontend on 3000, backend on 8000)
- 5Check that CORS middleware is added to FastAPI
- 6Verify "use client" is at the top of the file if using hooks
- 7Try a hard refresh (Cmd+Shift+R / Ctrl+Shift+R)
- 8Check if you're calling db.commit() after database changes