Optimistic state updates make your app feel faster by showing changes right away before the server confirms them.
0
0
Optimistic state updates in NextJS
Introduction
When you want to update a list item immediately after a user action, like liking a post.
When submitting a form and you want to show the new data instantly without waiting for the server.
When toggling a switch or button and you want the UI to respond instantly.
When you want to improve user experience by reducing waiting time after an action.
Syntax
NextJS
const [data, setData] = useState(initialData); async function updateData(newValue) { const previousData = data; // Update UI immediately setData(newValue); try { // Send update to server await fetch('/api/update', { method: 'POST', body: JSON.stringify(newValue), headers: { 'Content-Type': 'application/json' } }); } catch (error) { // Revert UI if server update fails setData(previousData); } }
Use setState to update UI before server response.
Handle errors to revert changes if server update fails.
Examples
Increment count optimistically without waiting for server.
NextJS
const [count, setCount] = useState(0); function increment() { setCount((prev) => prev + 1); // Update UI immediately fetch('/api/increment', { method: 'POST' }); }
Add an item to list optimistically and revert on error.
NextJS
const [items, setItems] = useState(['apple', 'banana']); async function addItem(item) { setItems([...items, item]); // Show new item right away try { await fetch('/api/add', { method: 'POST', body: JSON.stringify({ item }), headers: { 'Content-Type': 'application/json' } }); } catch { setItems(items); // Revert if error } }
Sample Program
This component lets users like or unlike something. It updates the button immediately when clicked. If the server update fails, it changes back and shows an error message.
NextJS
import React, { useState } from 'react'; export default function LikeButton() { const [liked, setLiked] = useState(false); const [error, setError] = useState(null); async function toggleLike() { const previousLiked = liked; setLiked(!liked); // Optimistic update setError(null); try { const response = await fetch('/api/like', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ liked: !liked }) }); if (!response.ok) throw new Error('Server error'); } catch (e) { setLiked(previousLiked); // Revert on error setError('Failed to update like status'); } } return ( <div> <button aria-pressed={liked} onClick={toggleLike} aria-label="Like button"> {liked ? '❤️ Liked' : '🤍 Like'} </button> {error && <p role="alert" style={{ color: 'red' }}>{error}</p>} </div> ); }
OutputSuccess
Important Notes
Always handle errors to keep UI and server data in sync.
Optimistic updates improve user experience but need careful rollback logic.
Use ARIA attributes like aria-pressed for accessibility on toggle buttons.
Summary
Optimistic updates show changes instantly before server confirms.
They make apps feel faster and more responsive.
Always plan to revert changes if server update fails.