Comprehensive collection of React hooks designed for modern React applications, offering utilities that extend beyond native React capabilities.
—
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Pending
The risk profile of this skill
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>
);
}