React useRef
Refs are escape hatches. Try to avoid using them where possible.
Ref Forwarding
Ref forwarding is a technique for automatically passing a ref through a component to one of its children.
Use when making a reusable componenent such as a custom button or custom input.
Reference:
Deferred Promise
Creating a deferred promise hook in React
// DeferredPromise.tsx
import { useRef } from 'react';
type DeferredPromise<DeferType> = {
resolve: (value: DeferType) => void;
reject: (value: unknown) => void;
promise: Promise<DeferType>;
};
export function useDeferredPromise<DeferType>() {
const deferRef = useRef<DeferredPromise<DeferType>>(null);
const defer = () => {
const deferred = {} as DeferredPromise<DeferType>;
const promise = new Promise<DeferType>((resolve, reject) => {
deferred.resolve = resolve;
deferred.reject = reject;
});
deferred.promise = promise;
deferRef.current = deferred;
return deferRef.current;
};
return { defer, deferRef: deferRef.current };
}
caution
When you defer a promise, never forget to resolve or reject it, otherwise you may encounter memory leak problems
Context
- Performance — When refs avoid unnecessary re-renders
- Anti-Patterns — Ref misuse patterns to avoid
- Hydration — Refs and the server-client boundary
Questions
When is a ref the right tool instead of state?
- What happens when you store derived data in a ref instead of computing it?
- How do you handle refs during server-side rendering where the DOM does not exist?
- When does ref forwarding add value versus passing callbacks?