export function useControl(CompIn) {
const ref = useRef();
// 通过 proxy 实现支持各种方法名
const methods = useMemo(() => createMethodsProxy(ref), []);
const CompOut = useMemo(() => {
if (!CompIn) {
return null;
}
const ControlledComp = function ControlledComp(props) {
return <CompIn {...props} ref={ref} />;
};
if (process.env.NODE_ENV === 'development') {
const originalName = CompIn.displayName ?? CompIn.name ?? 'Unknown';
ControlledComp.displayName = `useControl(${originalName})`;
}
return ControlledComp;
}, [CompIn]);
return [CompOut, methods];
}
function createMethodsProxy(ref) {
return new Proxy(
{
$get(property) {
return ref.current?.[property];
},
},
{
get(target, property) {
if (target[property]) {
return target[property];
}
const method = async (...args) => {
const fn = ref.current?.[property];
const value = fn && await fn(...args);
return value;
};
target[property] = method;
return method;
},
}
);
}
网友评论