How does Remix handle optimistic UI updates?

Answer

Optimistic UI in Remix shows immediate feedback before the server confirms a mutation. Use useNavigation for form submissions: const navigation = useNavigation(); const isLiking = navigation.formData?.get("action") === "like". Or with useFetcher: const fetcher = useFetcher(); const isLiked = fetcher.formData ? fetcher.formData.get("liked") === "true" : currentLiked;. The optimistic value is derived from the pending form data. When the server responds, Remix re-runs loaders and the real value replaces the optimistic one. For complex optimistic updates, maintain a local optimistic state: const optimisticList = fetcher.state === "submitting" ? [...items, optimisticItem] : items. Remix's approach is different from React Query's manual optimistic updates — you read pending state from the navigation/fetcher, making it simpler and less error-prone. The framework automatically handles the rollback if the server returns an error.