Hooks
No hooks found in any category.
useUpdateEffect
lifecycleInstallation
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
Name | Type | Default | Description |
---|---|---|---|
effect | React.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