Skip to content

Commit

Permalink
feat: Batch func to support React 18.3 findDOMNode (#537)
Browse files Browse the repository at this point in the history
* feat: support proxyObject

* chore: findDOMNode support nativeElement
  • Loading branch information
zombieJ authored May 17, 2024
1 parent 6d17201 commit c1dc1ed
Show file tree
Hide file tree
Showing 4 changed files with 68 additions and 1 deletion.
6 changes: 5 additions & 1 deletion src/Dom/findDOMNode.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,16 @@ export function isDOM(node: any): node is HTMLElement | SVGElement {
* Return if a node is a DOM node. Else will return by `findDOMNode`
*/
export default function findDOMNode<T = Element | Text>(
node: React.ReactInstance | HTMLElement | SVGElement,
node: React.ReactInstance | HTMLElement | SVGElement | { nativeElement: T },
): T {
if (isDOM(node)) {
return (node as unknown) as T;
}

if (node && typeof node === 'object' && isDOM((node as any).nativeElement)) {
return ((node as any).nativeElement as unknown) as T;
}

if (node instanceof React.Component) {
return (ReactDOM.findDOMNode(node) as unknown) as T;
}
Expand Down
25 changes: 25 additions & 0 deletions src/proxyObject.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
/**
* Proxy object if environment supported
*/
export default function proxyObject<
Obj extends object,
ExtendObj extends object
>(obj: Obj, extendProps: ExtendObj): Obj & ExtendObj {
if (typeof Proxy !== 'undefined') {
return new Proxy(obj, {
get(target, prop) {
if (extendProps[prop]) {
return extendProps[prop];
}

// Proxy origin property
const originProp = (target as any)[prop];
return typeof originProp === 'function'
? originProp.bind(target)
: originProp;
},
}) as Obj & ExtendObj;
}

return obj as Obj & ExtendObj;
}
23 changes: 23 additions & 0 deletions tests/findDOMNode.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -74,4 +74,27 @@ describe('findDOMNode', () => {
expect(true).toBeFalsy();
}
});

it('nativeElement', () => {
const Element = React.forwardRef<{ nativeElement: HTMLDivElement }>(
(_, ref) => {
const domRef = React.useRef<HTMLDivElement>(null);

React.useImperativeHandle(ref, () => ({
nativeElement: domRef.current!,
}));

return <p ref={domRef} />;
},
);

const elementRef = React.createRef<{ nativeElement: HTMLDivElement }>();
const { container } = render(
<React.StrictMode>
<Element ref={elementRef} />
</React.StrictMode>,
);

expect(findDOMNode(elementRef.current)).toBe(container.querySelector('p'));
});
});
15 changes: 15 additions & 0 deletions tests/proxyObject.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import proxyObject from '../src/proxyObject';

describe('proxyObject', () => {
it('work', () => {
const div = document.createElement('div');
div.innerHTML = '<a>noop</a>';
const a = div.firstChild as HTMLAnchorElement;

const proxyA = proxyObject(a, {
bamboo: 'little',
});

expect(proxyA.bamboo).toBe('little');
});
});

0 comments on commit c1dc1ed

Please sign in to comment.