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
Essential hooks for managing component state with stable references and optimized performance patterns.
Hook to store a boolean value and generate callbacks for setting the value to true or false. The identity of the callbacks will always stay the same, making it perfect for React.memo optimization.
/**
* Hook to store a value and generate callbacks for setting the value to true or false.
* The identity of the callbacks will always stay the same.
* @param initialState - Initial boolean value
* @returns Array with the current value and an object containing the updater callbacks
*/
function useBoolean(initialState: boolean): [boolean, IUseBooleanCallbacks];
interface IUseBooleanCallbacks {
/** Set the value to true. Always has the same identity. */
setTrue: () => void;
/** Set the value to false. Always has the same identity. */
setFalse: () => void;
/** Toggle the value. Always has the same identity. */
toggle: () => void;
}Usage Examples:
import { useBoolean } from "@fluentui/react-hooks";
function ToggleComponent() {
const [isVisible, { setTrue: show, setFalse: hide, toggle }] = useBoolean(false);
return (
<div>
<button onClick={show}>Show</button>
<button onClick={hide}>Hide</button>
<button onClick={toggle}>Toggle</button>
{isVisible && <div>This content is visible!</div>}
</div>
);
}
// Optimized with React.memo - callbacks won't cause re-renders
const OptimizedChild = React.memo(({ onToggle }: { onToggle: () => void }) => {
return <button onClick={onToggle}>Toggle from child</button>;
});
function ParentComponent() {
const [isActive, { toggle }] = useBoolean(false);
return (
<div>
<OptimizedChild onToggle={toggle} />
{isActive && <div>Active state</div>}
</div>
);
}Hook to initialize and return a constant value. Unlike React.useMemo, this is guaranteed to always return the same value and only call the initializer function once. Similar to setting a private member in a class constructor.
/**
* Hook to initialize and return a constant value. Unlike React.useMemo, this is guaranteed to
* always return the same value (and if the initializer is a function, only call it once).
* @param initialValue - Initial value, or function to get the initial value. Only the value/function
* passed in the first time this is called is respected.
* @returns The value. The identity of this value will always be the same.
*/
function useConst<T>(initialValue: T | (() => T)): T;Usage Examples:
import { useConst } from "@fluentui/react-hooks";
function ExpensiveComponent() {
// Expensive object creation - only runs once
const expensiveObject = useConst(() => ({
data: performExpensiveCalculation(),
cache: new Map(),
timestamp: Date.now()
}));
// Simple constant value
const componentId = useConst(() => `component-${Math.random()}`);
// Function constant
const stableCallback = useConst(() => () => {
console.log("This callback never changes");
});
return (
<div id={componentId}>
<div>Expensive data: {expensiveObject.data}</div>
<button onClick={stableCallback}>Stable callback</button>
</div>
);
}Hook to manage a value that could be either controlled or uncontrolled, such as a checked state or text box string. This pattern is essential for creating components that can work both in controlled and uncontrolled modes.
/**
* Hook to manage a value that could be either controlled or uncontrolled
* @param controlledValue - The controlled value passed in props. Always used if provided.
* @param defaultUncontrolledValue - Initial value for internal state in uncontrolled case.
* @returns Array of current value and updater callback with stable identity.
*/
function useControllableValue<TValue, TElement extends HTMLElement>(
controlledValue: TValue | undefined,
defaultUncontrolledValue: TValue | undefined
): Readonly<[TValue | undefined, (update: React.SetStateAction<TValue | undefined>) => void]>;
/**
* Overload with onChange callback for event handling
* @param controlledValue - The controlled value passed in props
* @param defaultUncontrolledValue - Initial value for internal state
* @param onChange - Callback fired when value changes
* @returns Array of current value and updater callback that calls onChange
*/
function useControllableValue<
TValue,
TElement extends HTMLElement,
TEvent extends React.SyntheticEvent<TElement> | undefined
>(
controlledValue: TValue | undefined,
defaultUncontrolledValue: TValue | undefined,
onChange: ChangeCallback<TElement, TValue, TEvent> | undefined
): Readonly<[
TValue | undefined,
(update: React.SetStateAction<TValue | undefined>, ev?: React.FormEvent<TElement>) => void
]>;
type ChangeCallback<
TElement extends HTMLElement,
TValue,
TEvent extends React.SyntheticEvent<TElement> | undefined
> = (ev: TEvent, newValue: TValue | undefined) => void;Usage Examples:
import { useControllableValue } from "@fluentui/react-hooks";
// Basic controllable input component
interface TextInputProps {
value?: string;
defaultValue?: string;
onChange?: (event: React.ChangeEvent<HTMLInputElement>, newValue: string | undefined) => void;
}
function TextInput({ value, defaultValue, onChange }: TextInputProps) {
const [currentValue, setValue] = useControllableValue(value, defaultValue, onChange);
const handleChange = (event: React.ChangeEvent<HTMLInputElement>) => {
setValue(event.target.value, event);
};
return (
<input
type="text"
value={currentValue || ""}
onChange={handleChange}
/>
);
}
// Usage as controlled component
function ControlledExample() {
const [text, setText] = useState("controlled");
return (
<TextInput
value={text}
onChange={(ev, newValue) => setText(newValue || "")}
/>
);
}
// Usage as uncontrolled component
function UncontrolledExample() {
return (
<TextInput
defaultValue="uncontrolled"
onChange={(ev, newValue) => console.log("Changed to:", newValue)}
/>
);
}/**
* @deprecated Deprecated due to potential for misuse. Generally, use React.useCallback instead.
* If you need a callback reference that never changes, consider useEventCallback.
*
* This hook was intended for creating callbacks which have no dependencies, and therefore never
* need to change. Usage tends to result in bugs like unintentionally capturing the first value
* of a prop and not respecting updates.
*/
function useConstCallback<T extends (...args: any[]) => any>(callback: T): T;Migration Guide:
// ❌ Deprecated useConstCallback
const callback = useConstCallback(() => {
// This captures the initial value and never updates
console.log(someProp);
});
// ✅ Use useEventCallback instead
const callback = useEventCallback(() => {
// This always uses the latest value
console.log(someProp);
});
// ✅ Or use React.useCallback with proper dependencies
const callback = useCallback(() => {
console.log(someProp);
}, [someProp]);