import {useCallback, useEffect, useRef} from 'react';
import {View} from 'react-native';
export interface ViewRect {
x: number;
y: number;
width: number;
height: number;
timestamp: number;
}
export function useViewProbe() {
const ref = useRef<View>(null);
const pending = useRef(new Map<ReturnType<typeof setTimeout>, (reason: Error) => void>());
useEffect(() => () => {
pending.current.forEach((reject, timer) => {
clearTimeout(timer);
reject(new Error('测量页面已卸载'));
});
pending.current.clear();
}, []);
const measure = useCallback(() => new Promise<ViewRect>((resolve, reject) => {
if (!ref.current) {
reject(new Error('测量节点尚未挂载,请先打开面板'));
return;
}
const timer = setTimeout(() => {
pending.current.delete(timer);
reject(new Error('measureInWindow 超时,未得到布局数据'));
}, 1500);
pending.current.set(timer, reject);
ref.current.measureInWindow((x, y, width, height) => {
if (!pending.current.has(timer)) return;
clearTimeout(timer);
pending.current.delete(timer);
if (![x, y, width, height].every(Number.isFinite) || width <= 0 || height <= 0) {
reject(new Error('measureInWindow 返回无效尺寸'));
return;
}
resolve({x, y, width, height, timestamp: Date.now()});
});
}), []);
return {ref, measure};
}