Hooks for handling component lifecycle events with proper cleanup and timing control.
Hook which asynchronously executes a callback once the component has been mounted. The callback is executed during the effect phase, not during render.
/**
* Hook which asynchronously executes a callback once the component has been mounted.
* @param callback - Function to call after mount.
*/
function useMount(callback: () => void): void;Usage Examples:
import { useMount } from "@fluentui/react-hooks";
function DataLoadingComponent() {
const [data, setData] = useState(null);
const [loading, setLoading] = useState(true);
useMount(() => {
// Fetch data when component mounts
fetchUserData()
.then(setData)
.finally(() => setLoading(false));
});
if (loading) return <div>Loading...</div>;
return <div>Data: {JSON.stringify(data)}</div>;
}
// Focus management on mount
function AutoFocusInput() {
const inputRef = useRef<HTMLInputElement>(null);
useMount(() => {
inputRef.current?.focus();
});
return <input ref={inputRef} placeholder="Auto-focused on mount" />;
}
// Analytics tracking
function AnalyticsComponent({ pageId }) {
useMount(() => {
// Track page view when component mounts
analytics.track('page_view', { pageId });
});
return <div>Page content...</div>;
}Hook which synchronously executes a callback when the component is about to unmount. Perfect for cleanup operations.
/**
* Hook which synchronously executes a callback when the component is about to unmount.
* @param callback - Function to call during unmount.
*/
function useUnmount(callback: () => void): void;Usage Examples:
import { useUnmount } from "@fluentui/react-hooks";
function WebSocketComponent() {
const [socket, setSocket] = useState(null);
useEffect(() => {
const ws = new WebSocket('ws://localhost:8080');
setSocket(ws);
}, []);
useUnmount(() => {
// Clean up WebSocket connection
if (socket) {
socket.close();
}
});
return <div>WebSocket component</div>;
}
// Event listener cleanup
function GlobalEventComponent() {
const handleKeyPress = (event) => {
console.log('Key pressed:', event.key);
};
useEffect(() => {
document.addEventListener('keypress', handleKeyPress);
}, []);
useUnmount(() => {
// Remove event listener on unmount
document.removeEventListener('keypress', handleKeyPress);
});
return <div>Press any key</div>;
}
// Analytics cleanup
function TrackingComponent({ userId }) {
useUnmount(() => {
// Send final analytics event before unmount
analytics.track('component_unmount', { userId });
});
return <div>Tracked component</div>;
}/**
* Hook which synchronously executes a callback once the component has been mounted.
*
* WARNING: This should only be used if you need to perform an action after the component has been
* mounted and before the browser paints. useMountSync will trigger debug warnings in server-rendered
* scenarios and should be used sparingly.
*
* @deprecated Consider to use React.useEffect() or React.useLayoutEffect() directly based on use case
* @param callback - Function to call once the component has been mounted.
*/
function useMountSync(callback: () => void): void;Migration Guide:
// ❌ Deprecated useMountSync
useMountSync(() => {
// Synchronous mount logic
});
// ✅ Use useLayoutEffect for synchronous DOM mutations
useLayoutEffect(() => {
// Synchronous DOM updates before browser paint
}, []);
// ✅ Use useEffect for most mount logic
useEffect(() => {
// Asynchronous mount logic
}, []);
// ✅ Use useMount for simple mount callbacks
useMount(() => {
// Simple mount callback
});Hook to force update a function component by updating a dummy state. Useful for cases where you need to trigger a re-render programmatically.
/**
* Hook to force update a function component by updating a dummy state.
* @returns Function that triggers a re-render when called
*/
function useForceUpdate(): () => void;Usage Examples:
import { useForceUpdate } from "@fluentui/react-hooks";
function ForceUpdateComponent() {
const forceUpdate = useForceUpdate();
const renderCount = useRef(0);
renderCount.current += 1;
return (
<div>
<div>Render count: {renderCount.current}</div>
<button onClick={forceUpdate}>Force Re-render</button>
</div>
);
}
// Use case: External data that doesn't trigger re-renders
function ExternalDataComponent() {
const forceUpdate = useForceUpdate();
// External data store that doesn't trigger React updates
const data = ExternalStore.getData();
useEffect(() => {
// Subscribe to external store
const unsubscribe = ExternalStore.subscribe(() => {
forceUpdate(); // Force re-render when external data changes
});
return unsubscribe;
}, [forceUpdate]);
return <div>External data: {data}</div>;
}Hook keeping track of a given value from a previous execution of the component. Useful for comparing current and previous values.
/**
* Hook keeping track of a given value from a previous execution of the component the Hook is used in.
* @param value - The value to track
* @returns The previous value, or undefined on first render
*/
function usePrevious<T>(value: T): T | undefined;Usage Examples:
import { usePrevious } from "@fluentui/react-hooks";
function ComparisonComponent({ count }: { count: number }) {
const previousCount = usePrevious(count);
return (
<div>
<div>Current count: {count}</div>
<div>Previous count: {previousCount ?? 'None'}</div>
{previousCount !== undefined && (
<div>
Count {count > previousCount ? 'increased' : 'decreased'} by {Math.abs(count - previousCount)}
</div>
)}
</div>
);
}
// Detecting prop changes
function PropChangeDetector({ userId, userName }) {
const previousUserId = usePrevious(userId);
const previousUserName = usePrevious(userName);
useEffect(() => {
if (previousUserId !== undefined && previousUserId !== userId) {
console.log('User ID changed from', previousUserId, 'to', userId);
// Perform cleanup or data refetch
}
}, [userId, previousUserId]);
useEffect(() => {
if (previousUserName !== undefined && previousUserName !== userName) {
console.log('User name changed from', previousUserName, 'to', userName);
}
}, [userName, previousUserName]);
return <div>User: {userName} (ID: {userId})</div>;
}
// Animation triggers
function AnimationComponent({ isVisible }) {
const wasVisible = usePrevious(isVisible);
const [animationClass, setAnimationClass] = useState('');
useEffect(() => {
if (wasVisible !== undefined) {
if (!wasVisible && isVisible) {
setAnimationClass('fade-in');
} else if (wasVisible && !isVisible) {
setAnimationClass('fade-out');
}
}
}, [isVisible, wasVisible]);
return (
<div className={`content ${animationClass}`}>
Content visibility: {isVisible ? 'visible' : 'hidden'}
</div>
);
}