Skip to content

useRef$

An observable element ref hook that serves as a drop-in replacement for useRef. Works with callback ref composition and forwardRef patterns. The element is wrapped with opaqueObject to prevent legendapp/state from deeply observing DOM properties.

import { useRef$ } from "@usels/web";
function Component() {
const el$ = useRef$<HTMLDivElement>();
return <div ref={el$} />;
}

Calling el$.get() inside useObserve automatically re-runs the observer when the element is mounted or unmounted.

import { useObserve } from "@legendapp/state/react";
import { useRef$ } from "@usels/web";
function Component() {
const el$ = useRef$<HTMLDivElement>();
useObserve(() => {
const el = el$.get();
if (el) {
el.focus();
}
});
return <div ref={el$} />;
}
import { forwardRef } from "react";
import { useRef$ } from "@usels/web";
const Component = forwardRef<HTMLDivElement>((props, ref) => {
const el$ = useRef$(ref);
useObserve(() => {
const el = el$.get();
if (el) {
console.log("element mounted:", el);
}
});
return <div ref={el$} />;
});
export type Ref$<T> = ((node: T | null) => void) & {
get(): OpaqueObject<T> | null;
peek(): OpaqueObject<T> | null;
};
export type MaybeElement = Ref$<any> | Document | Window | null | undefined | Observable<OpaqueObject<Element> | null>;
export declare function useRef$<T extends Element = Element>(externalRef?: Ref<T> | null): Ref$<T>;
export declare function isRef$(v: unknown): v is Ref$<Element>;
export declare function getElement(v: MaybeElement): HTMLElement | Document | Window | null;
export declare function peekElement(v: MaybeElement): HTMLElement | Document | Window | null;

View on GitHub

  • tigerwest
  • a7392ab 2026-03-06 - feat(core,browser): add sync strategy hooks (tigerwest)