Skip to content

Commit c1dc1ed

Browse files
authored
feat: Batch func to support React 18.3 findDOMNode (#537)
* feat: support proxyObject * chore: findDOMNode support nativeElement
1 parent 6d17201 commit c1dc1ed

File tree

4 files changed

+68
-1
lines changed

4 files changed

+68
-1
lines changed

src/Dom/findDOMNode.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,16 @@ export function isDOM(node: any): node is HTMLElement | SVGElement {
1111
* Return if a node is a DOM node. Else will return by `findDOMNode`
1212
*/
1313
export default function findDOMNode<T = Element | Text>(
14-
node: React.ReactInstance | HTMLElement | SVGElement,
14+
node: React.ReactInstance | HTMLElement | SVGElement | { nativeElement: T },
1515
): T {
1616
if (isDOM(node)) {
1717
return (node as unknown) as T;
1818
}
1919

20+
if (node && typeof node === 'object' && isDOM((node as any).nativeElement)) {
21+
return ((node as any).nativeElement as unknown) as T;
22+
}
23+
2024
if (node instanceof React.Component) {
2125
return (ReactDOM.findDOMNode(node) as unknown) as T;
2226
}

src/proxyObject.ts

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
/**
2+
* Proxy object if environment supported
3+
*/
4+
export default function proxyObject<
5+
Obj extends object,
6+
ExtendObj extends object
7+
>(obj: Obj, extendProps: ExtendObj): Obj & ExtendObj {
8+
if (typeof Proxy !== 'undefined') {
9+
return new Proxy(obj, {
10+
get(target, prop) {
11+
if (extendProps[prop]) {
12+
return extendProps[prop];
13+
}
14+
15+
// Proxy origin property
16+
const originProp = (target as any)[prop];
17+
return typeof originProp === 'function'
18+
? originProp.bind(target)
19+
: originProp;
20+
},
21+
}) as Obj & ExtendObj;
22+
}
23+
24+
return obj as Obj & ExtendObj;
25+
}

tests/findDOMNode.test.tsx

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,4 +74,27 @@ describe('findDOMNode', () => {
7474
expect(true).toBeFalsy();
7575
}
7676
});
77+
78+
it('nativeElement', () => {
79+
const Element = React.forwardRef<{ nativeElement: HTMLDivElement }>(
80+
(_, ref) => {
81+
const domRef = React.useRef<HTMLDivElement>(null);
82+
83+
React.useImperativeHandle(ref, () => ({
84+
nativeElement: domRef.current!,
85+
}));
86+
87+
return <p ref={domRef} />;
88+
},
89+
);
90+
91+
const elementRef = React.createRef<{ nativeElement: HTMLDivElement }>();
92+
const { container } = render(
93+
<React.StrictMode>
94+
<Element ref={elementRef} />
95+
</React.StrictMode>,
96+
);
97+
98+
expect(findDOMNode(elementRef.current)).toBe(container.querySelector('p'));
99+
});
77100
});

tests/proxyObject.test.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import proxyObject from '../src/proxyObject';
2+
3+
describe('proxyObject', () => {
4+
it('work', () => {
5+
const div = document.createElement('div');
6+
div.innerHTML = '<a>noop</a>';
7+
const a = div.firstChild as HTMLAnchorElement;
8+
9+
const proxyA = proxyObject(a, {
10+
bamboo: 'little',
11+
});
12+
13+
expect(proxyA.bamboo).toBe('little');
14+
});
15+
});

0 commit comments

Comments
 (0)