Bird
Raised Fist0
NextJSframework~20 mins

Optimistic updates pattern in NextJS - Practice Problems & Coding Challenges

Choose your learning style10 modes available

Start learning this pattern below

Jump into concepts and practice - no test required

or
Recommended
Test this pattern10 questions across easy, medium, and hard to know if this pattern is strong
Challenge - 5 Problems
🎖️
Optimistic Updates Master
Get all challenges correct to earn this badge!
Test your skills under time pressure!
component_behavior
intermediate
2:00remaining
What happens immediately after triggering an optimistic update?
Consider a Next.js component using optimistic updates to add a new item to a list. What will the user see right after clicking the add button, before the server confirms?
NextJS
const [items, setItems] = useState(['apple', 'banana']);

async function addItem(newItem) {
  setItems([...items, newItem]); // optimistic update
  await fetch('/api/add', { method: 'POST', body: JSON.stringify({ item: newItem }) });
  // no rollback on failure here
}

// User clicks button to add 'orange'
AThe list immediately shows 'orange' added, even before server response.
BThe list removes all items temporarily during the request.
CThe list waits until server confirms before showing 'orange'.
DThe list shows an error message immediately after clicking.
Attempts:
2 left
💡 Hint
Think about what optimistic update means: showing changes before confirmation.
state_output
intermediate
2:00remaining
What is the state of the list after a failed optimistic update?
Given this Next.js code snippet using optimistic updates, what will be the final state of the items if the server request fails and no rollback is implemented?
NextJS
const [items, setItems] = useState(['cat', 'dog']);

async function addPet(pet) {
  setItems([...items, pet]); // optimistic update
  try {
    const res = await fetch('/api/addPet', { method: 'POST', body: JSON.stringify({ pet }) });
    if (!res.ok) throw new Error('Failed');
  } catch {
    // no rollback
  }
}

// addPet('rabbit') is called but server returns error
AThe list becomes empty due to error.
B['cat', 'dog'] remains because rollback removes 'rabbit'.
C['cat', 'dog', 'rabbit'] remains in the list.
DThe list shows only 'rabbit'.
Attempts:
2 left
💡 Hint
No rollback means the optimistic change stays even if server fails.
🔧 Debug
advanced
2:00remaining
Why does this optimistic update cause a UI flicker?
Examine this Next.js code using optimistic updates. Why does the UI flicker when adding a new item?
NextJS
const [items, setItems] = useState([]);

async function addItem(item) {
  setItems([]); // clear list first
  setItems([...items, item]); // optimistic update
  await fetch('/api/add', { method: 'POST', body: JSON.stringify({ item }) });
}

// User adds 'pear'
ABecause setItems is called twice in a row, which is invalid syntax.
BBecause the fetch call is blocking the UI thread.
CBecause the optimistic update is missing a rollback.
DBecause the list is cleared before adding, causing a brief empty render.
Attempts:
2 left
💡 Hint
Think about what happens when you clear the list before adding.
📝 Syntax
advanced
2:00remaining
Which option correctly implements rollback on optimistic update failure?
You want to optimistically add an item but revert if the server fails. Which code snippet correctly implements rollback?
A
setItems([...items, newItem]);
await fetch('/api/add', { method: 'POST', body: JSON.stringify({ newItem }) });
setItems(items);
B
const oldItems = [...items];
setItems([...items, newItem]);
try {
  await fetch('/api/add', { method: 'POST', body: JSON.stringify({ newItem }) });
} catch {
  setItems(oldItems);
}
C
setItems([...items, newItem]);
try {
  await fetch('/api/add', { method: 'POST', body: JSON.stringify({ newItem }) });
} catch {
  setItems([]);
}
D
const oldItems = items;
setItems([...items, newItem]);
await fetch('/api/add', { method: 'POST', body: JSON.stringify({ newItem }) });
setItems(oldItems);
Attempts:
2 left
💡 Hint
Rollback means restoring previous state only if fetch fails.
🧠 Conceptual
expert
2:00remaining
Why is optimistic update pattern beneficial in Next.js apps?
Select the best explanation for why optimistic updates improve user experience in Next.js applications.
AThey make the UI feel faster by showing changes immediately without waiting for server response.
BThey guarantee data consistency by waiting for server confirmation before updating UI.
CThey reduce server load by batching multiple requests into one.
DThey prevent any errors by disabling user input during server requests.
Attempts:
2 left
💡 Hint
Think about user perception of speed and responsiveness.

Practice

(1/5)
1. What is the main idea behind the optimistic updates pattern in Next.js?
easy
A. Update the UI immediately before server confirmation to improve user experience
B. Wait for server response before updating the UI to ensure accuracy
C. Reload the entire page after every data change to keep UI fresh
D. Disable user input until the server confirms the update

Solution

  1. Step 1: Understand the purpose of optimistic updates

    Optimistic updates aim to make the app feel faster by showing changes immediately.
  2. Step 2: Compare UI update timing

    Instead of waiting for the server, the UI updates first, then confirms or reverts based on server response.
  3. Final Answer:

    Update the UI immediately before server confirmation to improve user experience -> Option A
  4. Quick Check:

    Optimistic updates = Immediate UI update [OK]
Hint: UI updates first, server confirms later [OK]
Common Mistakes:
  • Waiting for server before UI update
  • Reloading entire page unnecessarily
  • Disabling user input during update
2. Which of the following is the correct way to implement an optimistic update in Next.js using React hooks?
easy
A. Use useEffect to update state only after server confirms
B. Send API request first, then call setState after response
C. Call setState to update UI, then send API request, revert on error
D. Reload the page after API call to update UI

Solution

  1. Step 1: Identify optimistic update flow

    Optimistic update means updating UI state immediately with setState.
  2. Step 2: Confirm API call and handle errors

    Send API request after UI update, and revert state if the request fails.
  3. Final Answer:

    Call setState to update UI, then send API request, revert on error -> Option C
  4. Quick Check:

    Update state first, then API call [OK]
Hint: Update state first, then call API [OK]
Common Mistakes:
  • Waiting for API before updating state
  • Using useEffect incorrectly for optimistic update
  • Reloading page instead of updating state
3. Consider this Next.js React component snippet using optimistic updates:
const [likes, setLikes] = useState(0);

async function handleLike() {
  setLikes(likes + 1);
  try {
    await fetch('/api/like', { method: 'POST' });
  } catch {
    setLikes(likes); // revert on error
  }
}

What will the UI show if the API call fails?
medium
A. The likes count stays incremented by 1
B. The likes count increments by 2
C. The likes count resets to zero
D. The likes count reverts to the original value

Solution

  1. Step 1: Analyze optimistic update behavior

    The UI increments likes immediately by 1 using setLikes(likes + 1).
  2. Step 2: Check error handling

    If the API call fails, setLikes(likes) resets likes to the original value before increment.
  3. Final Answer:

    The likes count reverts to the original value -> Option D
  4. Quick Check:

    API error triggers revert to old likes [OK]
Hint: Revert state on API failure [OK]
Common Mistakes:
  • Assuming UI stays incremented after failure
  • Resetting likes to zero incorrectly
  • Incrementing likes twice by mistake
4. You wrote this optimistic update code in Next.js but the UI never reverts on API failure:
const [count, setCount] = useState(0);

async function increment() {
  setCount(count + 1);
  try {
    await fetch('/api/increment', { method: 'POST' });
  } catch {
    setCount(count - 1);
  }
}

What is the bug causing the revert to fail?
medium
A. Using stale count value inside catch block
B. Not awaiting the setCount call
C. Missing return statement after setCount
D. API call method should be GET, not POST

Solution

  1. Step 1: Understand state closure issue

    The count variable inside catch is the old value before increment.
  2. Step 2: Explain why revert fails

    Subtracting 1 from stale count does not revert to original because count was already incremented in UI.
  3. Final Answer:

    Using stale count value inside catch block -> Option A
  4. Quick Check:

    State closure causes revert failure [OK]
Hint: Avoid stale state in async error handlers [OK]
Common Mistakes:
  • Expecting setState to be async
  • Ignoring stale closure of state variable
  • Wrong HTTP method for API call
5. You want to implement optimistic updates for a comment submission in Next.js. Which approach best handles UI update, server confirmation, and error rollback?
hard
A. Reload the page after comment submission to show new comment
B. Add comment to UI state immediately, send API request, remove comment if API fails
C. Add comment to UI state only after API confirms success
D. Send API request first, then add comment to UI state after success

Solution

  1. Step 1: Apply optimistic update pattern

    Update UI immediately by adding comment to state to improve responsiveness.
  2. Step 2: Handle server confirmation and errors

    Send API request; if it fails, remove the comment from UI to keep data consistent.
  3. Final Answer:

    Add comment to UI state immediately, send API request, remove comment if API fails -> Option B
  4. Quick Check:

    UI update first, revert on error [OK]
Hint: Add UI item first, remove on failure [OK]
Common Mistakes:
  • Waiting for API before UI update
  • Adding comment only after success
  • Reloading page instead of updating state