Common Gotchas

These are the most common mistakes in full-stack interviews. Know them by heart.

ProblemSolution
CORS errors in consoleAdd CORSMiddleware to FastAPI (first thing!)
"use client" missingAdd it for any component with state/effects
Missing key prop warningAlways add key={uniqueId} in .map()
Form refreshes the pageAdd e.preventDefault() in onSubmit
State not updating immediatelyState updates are async — use functional updates
Infinite useEffect loopCheck your dependency array — don't include objects/arrays
Cannot read property of undefinedAdd loading states, check data exists before accessing
API returns HTML instead of JSONCheck the URL — probably hitting wrong endpoint
Changes not persistingMake sure you're calling db.commit() in FastAPI
WebSocket won't connectUse 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.

CORS Fix
1from fastapi.middleware.cors import CORSMiddleware
2
3app = FastAPI()
4
5# ADD THIS RIGHT AFTER CREATING THE APP
6app.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).

use client Fix
1"use client" // Must be FIRST LINE
2
3import { useState } from "react"
4
5export 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.

Form Submit Fix
1const handleSubmit = async (e: React.FormEvent) => {
2 e.preventDefault() // CRITICAL! Prevents page reload
3
4 // Now handle the submission
5 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.

Key Prop Fix
1// WRONG - No key
2{items.map((item) => (
3 <div>{item.name}</div>
4))}
5
6// CORRECT - Has unique key
7{items.map((item) => (
8 <div key={item.id}>{item.name}</div>
9))}
10
11// 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.

State Update Fix
1// WRONG - count is still 0 after this
2setCount(count + 1)
3console.log(count) // Still 0!
4
5// CORRECT - Use functional update for derived state
6setCount(prev => prev + 1)
7
8// CORRECT - Watch with useEffect
9useEffect(() => {
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.

useEffect Fix
1// WRONG - options object is recreated every render
2const options = { limit: 10 }
3useEffect(() => {
4 fetchData(options)
5}, [options]) // Infinite loop!
6
7// CORRECT - Use primitive values
8const limit = 10
9useEffect(() => {
10 fetchData({ limit })
11}, [limit])
12
13// CORRECT - Empty array for "run once"
14useEffect(() => {
15 fetchData()
16}, [])

Debugging Checklist

When Something Isn't Working:

  1. 1Check the browser console for errors (F12 → Console)
  2. 2Check the network tab for failed requests (F12 → Network)
  3. 3Check the terminal running FastAPI for Python errors
  4. 4Verify both servers are running (frontend on 3000, backend on 8000)
  5. 5Check that CORS middleware is added to FastAPI
  6. 6Verify "use client" is at the top of the file if using hooks
  7. 7Try a hard refresh (Cmd+Shift+R / Ctrl+Shift+R)
  8. 8Check if you're calling db.commit() after database changes