Package Exports
- @uifabric/react-hooks
This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (@uifabric/react-hooks) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.
Readme
@uifabric/react-hooks
Fluent UI React hooks
Helpful hooks not provided by React itself. These hooks were built for use in Fluent UI React (formerly Office UI Fabric React) but can be used in React apps built with any UI library.
- useBoolean - Return a boolean value and callbacks for setting it to true or false, or toggling
- useConst - Initialize and return a value that's always constant
- useConstCallback - Like
useConst
but for functions - useControllableValue - Manage the current value for a component that could be either controlled or uncontrolled
- useForceUpdate - Force a function component to update
- useId - Get a globally unique ID
- useMergedRefs - Merge multiple refs into a single ref callback
- useOnEvent - Attach an event handler on mount and handle cleanup
- usePrevious - Get a value from the previous execution of the component
- useRefEffect - Call a function with cleanup when a ref changes. Like
useEffect
with a dependency on a ref. - useSetInterval - Version of
setInterval
that automatically cleans up when component is unmounted - useSetTimeout - Version of
setTimeout
that automatically cleans up when component is unmounted
useBoolean
function useBoolean(initialState: boolean): [boolean, IUseBooleanCallbacks];
interface IUseBooleanCallbacks {
setTrue: () => void;
setFalse: () => void;
toggle: () => void;
}
Hook to store a boolean state value and generate callbacks for setting the value to true or false, or toggling the value.
The hook returns a tuple containing the current value and an object with callbacks for updating the value.
Each callback will always have the same identity.
Example
import { useBoolean } from '@uifabric/react-hooks';
const MyComponent = () => {
const [value, { setTrue: showDialog, setFalse: hideDialog, toggle: toggleDialogVisible }] = useBoolean(false);
// ^^^ Instead of:
// const [isDialogVisible, setIsDialogVisible] = React.useState(false);
// const showDialog = useConstCallback(() => setIsDialogVisible(true));
// const hideDialog = useConstCallback(() => setIsDialogVisible(false));
// const toggleDialogVisible = isDialogVisible ? setFalse : setTrue;
// ... code that shows a dialog when a button is clicked ...
};
useConst
function useConst<T>(initialValue: T | (() => T)): T;
Hook to initialize and return a constant value. Unlike React.useMemo
, this will always return the same value (and if the initializer is a function, only call it once). This is similar to setting a private member in a class constructor.
Its one parameter is the initial value, or a function to get the initial value. Similar to useState
, only the first value/function passed in is respected.
If the value should ever change based on dependencies, use React.useMemo
instead.
If the value itself is a function, consider using useConstCallback
instead.
Example
import { useConst } from '@uifabric/react-hooks';
const MyComponent = () => {
const value = useConst(() => {
/* some computation that must only run once or has side effects */
});
const valueThatMustNeverChange = useConst(/*...*/);
...
};
Why not just useMemo
?
According to the React docs:
You may rely on
useMemo
as a performance optimization, not as a semantic guarantee. In the future, React may choose to “forget” some previously memoized values and recalculate them on next render, e.g. to free memory for offscreen components. Write your code so that it still works withoutuseMemo
— and then add it to optimize performance.
In cases where the value must never change, the recommended workaround is to store it with useRef
, but refs are more awkward to initialize and don't enforce or even communicate that the value should be immutable. An alternative workaround is const [value] = useState(initializer)
, but this is semantically wrong and more costly under the hood.
useConstCallback
function useConstCallback<T extends (...args: any[]) => any>(callback: T): T;
Hook to ensure a callback function always has the same identity. Unlike React.useCallback
, this is guaranteed to always return the same value.
Its one parameter is the callback. Similar to useState
, only the first value/function passed in is respected.
If the callback should ever change based on dependencies, use React.useCallback
instead.
useConstCallback(fn)
has the same behavior as useConst(() => fn)
.
useControllableValue
function useControllableValue<TValue, TElement extends HTMLElement>(
controlledValue: TValue | undefined,
defaultUncontrolledValue: TValue | undefined,
): Readonly<[TValue | undefined, (newValue: TValue | undefined) => void]>;
function useControllableValue<
TValue,
TElement extends HTMLElement,
TCallback extends ChangeCallback<TElement, TValue> | undefined
>(
controlledValue: TValue | undefined,
defaultUncontrolledValue: TValue | undefined,
onChange: TCallback,
): Readonly<[TValue | undefined, (newValue: TValue | undefined, ev: React.FormEvent<TElement>) => void]>;
type ChangeCallback<TElement extends HTMLElement, TValue> = (
ev: React.FormEvent<TElement> | undefined,
newValue: TValue | undefined,
) => void;
Hook to manage the current value for a component that could be either controlled or uncontrolled, such as a checkbox or input field.
Its two required parameters are the controlledValue
(the current value of the control in the controlled state), and the defaultUncontrolledValue
(for the uncontrolled state). Optionally, you may pass a third onChange
callback to be notified of any changes triggered by the control.
The return value will be a setter function that will set the internal state in the uncontrolled state, and invoke the onChange
callback if present.
See React docs about the distinction between controlled and uncontrolled components.
useForceUpdate
function useForceUpdate(): () => void;
Returns a function which, when called, will force update a function component by updating a fake state value.
The returned function always has the same identity.
useId
function useId(prefix?: string): string;
Hook to generate a unique ID (with optional prefix
) in the global scope. This will return the same ID on every render.
Useful for cases in which a component may be rendered multiple times on the same page and needs to use an ID for internal purposes, such as associating a label and an input.
Example
import { useId } from '@uifabric/react-hooks';
const TextField = ({ labelText, defaultValue }) => {
const id = useId('field');
return (
<div>
<label htmlFor={id}>{labelText}</label>
<input id={id} type="text" defaultValue={defaultValue} />
</div>
);
};
useMergedRefs
function useMergedRefs<T>(...refs: React.Ref<T>[]): (instance: T) => void;
Hook to merge multiple refs (such as one passed in as a prop and one used locally) into a single ref callback that can be passed on to a child component.
const Example = React.forwardRef(function Example(props: {}, forwardedRef: React.Ref<HTMLDivElement>) {
const localRef = React.useRef<HTMLDivElement>();
const mergedRef = useMergedRef(localRef, forwardedRef);
React.useEffect(() => {
localRef.current.focus();
}, []);
return <div>Example</div>;
});
useOnEvent
function useOnEvent<TElement extends Element, TEvent extends Event>(
element: React.RefObject<TElement | undefined | null> | TElement | Window | undefined | null,
eventName: string,
callback: (ev: TEvent) => void,
useCapture?: boolean,
): void;
Attach an event handler on mount and handle cleanup. The event handler is attached using on()
from @uifabric/utilities
.
usePrevious
function usePrevious<T>(value: T): T | undefined;
Hook keeping track of a given value from a previous execution of the component the Hook is used in. See React Hooks FAQ.
useRefEffect
function useRefEffect<T>(callback: (value: T) => (() => void) | void, initial: T | null = null): RefCallback<T>;
type RefCallback<T> = ((value: T | null) => void) & React.RefObject<T>;
Creates a ref, and calls a callback whenever the ref changes to a non-null value. The callback can optionally return a cleanup function that'll be called before the value changes, and when the ref is unmounted.
The return value is a function that should be called to set the ref's value. The returned object also has a .current
member that can be used to access the ref's value (like a normal RefObject
). This can be hooked up to an element's ref
property.
useRefEffect
can be used to work around a limitation that useEffect
cannot depend on ref.current
.
Example
import { useRefEffect } from '@uifabric/react-hooks';
const MyComponent = () => {
const myDivRef = useRefEffect<HTMLElement>(myDiv => {
const observer = new ResizeObserver(entries => {
console.log(`myDiv is ${entries[0].contentRect.width} px wide`);
});
observer.observe(myDiv);
// Return a function to clean up the ResizeObserver when the ref is unmounted
return () => observer.disconnect();
});
return <div ref={myDivRef} />;
};
useSetInterval
function useSetInterval(): {
setInterval: (callback: () => void, duration: number) => number;
clearInterval: (id: number) => void;
};
Hook which returns safe setInterval
and clearInterval
methods. Intervals set up using this hook will be automatically cleared when the component is unmounted.
The returned callbacks always have the same identity.
Example
import { useSetInterval } from '@uifabric/react-hooks';
const MyComponent = () => {
const { setInterval, clearInterval } = useSetInterval();
// Set an interval
const id = setInterval(() => console.log('test'), 500);
// If needed, clear an interval manually.
clearInterval(id);
};
useSetTimeout
function useSetTimeout(): {
setTimeout: (callback: () => void, duration: number) => number;
clearTimeout: (id: number) => void;
};
Hook which returns safe setTimeout
and clearTimeout
methods. Timeout callbacks set up using this hook will be automatically cleared when the component is unmounted.
The returned callbacks always have the same identity.
Example
import { useSetTimeout } from '@uifabric/react-hooks';
const MyComponent = () => {
const { setTimeout, clearTimeout } = useSetTimeout();
// Set a timeout
const id = setTimeout(() => console.log('test'), 500);
// If needed, clear an timeout manually.
clearTimeout(id);
};