useHooks.iov4.1.2
DocsBlogGitHub
Hooks
No hooks found in any category.

useUpdateEffect

lifecycle

Installation

npx usehooks-cli@latest add use-update-effect

Description

A React hook that works like useEffect but skips the first render. Only runs the effect on subsequent updates, not on component mount.

Parameters

NameTypeDefaultDescription
effectReact.EffectCallback-The effect function to run on updates (not on mount)
deps?React.DependencyList-Array of dependencies to watch for changes

Examples

Skip Initial API Call

Only making API calls on updates, not on initial mount

1const [userId, setUserId] = useState(1); 2const [userData, setUserData] = useState(null); 3 4// Regular useEffect - runs on mount and updates 5useEffect(() => { 6 // Initial data load 7 fetchUserData(userId).then(setUserData); 8}, [userId]); 9 10// Update effect - only runs when userId changes after mount 11useUpdateEffect(() => { 12 // This won't run on the initial render 13 console.log('User changed, updating data...'); 14 fetchUserData(userId).then(setUserData); 15 16 // Show loading indicator for updates only 17 setIsUpdating(true); 18}, [userId]);

Form Validation on Changes

Validating form only after user starts making changes

1const [formData, setFormData] = useState({ 2 email: '', 3 password: '', 4 confirmPassword: '' 5}); 6const [errors, setErrors] = useState({}); 7 8// Don't validate on initial render, only when user changes form 9useUpdateEffect(() => { 10 const newErrors = validateForm(formData); 11 setErrors(newErrors); 12 13 // Show validation messages only after user interaction 14 if (Object.keys(newErrors).length > 0) { 15 showValidationToast('Please fix the errors'); 16 } 17}, [formData]); 18 19const handleInputChange = (field, value) => { 20 setFormData(prev => ({ ...prev, [field]: value })); 21};

Analytics Tracking

Tracking user interactions without counting initial page load

1const [currentPage, setCurrentPage] = useState('home'); 2const [searchQuery, setSearchQuery] = useState(''); 3const [filters, setFilters] = useState([]); 4 5// Track page changes (excluding initial page load) 6useUpdateEffect(() => { 7 analytics.track('page_changed', { 8 from: previousPage, 9 to: currentPage, 10 timestamp: Date.now() 11 }); 12}, [currentPage]); 13 14// Track search behavior (excluding initial empty state) 15useUpdateEffect(() => { 16 if (searchQuery.trim()) { 17 analytics.track('search_performed', { 18 query: searchQuery, 19 filters: filters, 20 resultsCount: searchResults.length 21 }); 22 } 23}, [searchQuery, filters]); 24 25// Track filter usage (excluding initial empty filters) 26useUpdateEffect(() => { 27 analytics.track('filters_applied', { 28 filters: filters, 29 count: filters.length 30 }); 31}, [filters]);

Dependencies

react

Notes

  • Skips execution on the first render (component mount)
  • Useful for avoiding unwanted side effects during initial component setup
  • Commonly used for analytics, validation, and update-specific logic
  • Uses a ref to track whether it's the first render
  • Behaves exactly like useEffect for all subsequent renders
  • Cleanup function works the same as regular useEffect

Implementation

1"use client"; 2 3import { useEffect, useRef } from "react"; 4 5export function useUpdateEffect( 6 effect: React.EffectCallback, 7 deps?: React.DependencyList 8): void { 9 const isFirstRender = useRef(true); 10 11 useEffect(() => { 12 if (isFirstRender.current) { 13 isFirstRender.current = false; 14 return; 15 } 16 17 return effect(); 18 }, deps); 19} 20