-
-
Notifications
You must be signed in to change notification settings - Fork 2k
/
Copy pathforwardRef.js
40 lines (35 loc) · 1.28 KB
/
forwardRef.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
import { options } from 'preact';
import { assign } from './util';
let oldDiffHook = options._diff;
options._diff = vnode => {
if (vnode.type && vnode.type._forwarded && vnode.ref) {
vnode.props.ref = vnode.ref;
vnode.ref = null;
}
if (oldDiffHook) oldDiffHook(vnode);
};
export const REACT_FORWARD_SYMBOL = Symbol.for('react.forward_ref');
/**
* Pass ref down to a child. This is mainly used in libraries with HOCs that
* wrap components. Using `forwardRef` there is an easy way to get a reference
* of the wrapped component instead of one of the wrapper itself.
* @param {import('./index').ForwardFn} fn
* @returns {import('./internal').FunctionComponent}
*/
export function forwardRef(fn) {
function Forwarded(props) {
let clone = assign({}, props);
delete clone.ref;
return fn(clone, props.ref || null);
}
// mobx-react checks for this being present
Forwarded.$$typeof = REACT_FORWARD_SYMBOL;
// mobx-react heavily relies on implementation details.
// It expects an object here with a `render` property,
// and prototype.render will fail. Without this
// mobx-react throws.
Forwarded.render = Forwarded;
Forwarded.prototype.isReactComponent = Forwarded._forwarded = true;
Forwarded.displayName = 'ForwardRef(' + (fn.displayName || fn.name) + ')';
return Forwarded;
}