-
-
Save jamesreggio/142215754ad06f375bd87657c6227ed8 to your computer and use it in GitHub Desktop.
// EmailInput wraps an HTML `input` and adds some app-specific styling. | |
const EmailInput = React.forwardRef((props, ref) => ( | |
<input ref={ref} {...props} type="email" className="AppEmailInput" /> | |
)); | |
class App extends Component { | |
emailRef = React.createRef(); | |
render() { | |
return ( | |
<div> | |
<EmailInput ref={this.emailRef} /> | |
<button onClick={() => this.onClickButton()}> | |
Click me to focus email | |
</button> | |
</div> | |
); | |
} | |
// `this.emailRef.current` points to the `input` component inside of EmailInput, | |
// because EmailInput is forwarding its ref via the `React.forwardRef` callback. | |
onClickButton() { | |
this.emailRef.current.focus(); | |
} | |
} |
I feel this discussion also explains better - forwardRef
function vs a custom ref
https://stackoverflow.com/questions/58578570/value-of-using-react-forwardref-vs-custom-ref-prop
We use both in our project and while the former offers a way to pass a reference to the inner elements (to the root element that actually appears in the HTML dom), the latter can provide a way to pass ones that you already have might have declared in the component that is calling another.
Example: Check out use-resize-observer
package: https://github.com/ZeeCoder/use-resize-observer
thanks work fine for my case !
here cool example for types and control a powerful componement
export const Box = React.forwardRef(
/**
* @typedef {Object} FlexOption
* @property {React.CSSProperties['display']} [FlexOption.display]
* @property {React.CSSProperties['flexDirection']} [dir]
* @property {React.CSSProperties['flexGrow']} [grow]
* @property {React.CSSProperties['flexFlow']} [flow]
* @typedef {Object} props
* @property {boolean | FlexOption} [Flex] -
* @property {boolean | 'reverse' } [Column] -
* @property {boolean | number } [Grow] -
* @property { React.CSSProperties['position'] } [Position] -
* @property {bgcolor} [ColorBg] - colors
* @property {boolean|number} [Fit] - number % w,h
* @property {boolean|React.CSSProperties['overflowX']} [OverflowX] -
* @property {boolean|React.CSSProperties['overflowY']} [OverflowY] -
* @property {number|{x:number,y:number}|[number,number,number,number]} [P] - padding: [ left, top, right, bottom ]
* @property {number|'auto'|{x:number,y:number}|[number,number,number,number]} [M] - margin: [ left, top, right, bottom ]
* @typedef {props & React.HTMLAttributes<HTMLDivElement> } Child
* @param {Child} props Component props
*/
(
{ Flex, Column, Grow, ColorBg, Fit, Position, P, M, OverflowX, OverflowY, children, style = {}, ...rest },
ref,
) => {
if (Flex || Column) {
style.display = style.display || 'flex';
}
if (Column) {
style.flexDirection = _.isString(Column) ? 'column-reverse' : 'column';
}
if (Grow) {
style.flexGrow = +Grow;
}
if (Position) {
style.position = Position;
}
if (ColorBg) {
style.backgroundColor = ColorBg;
}
if (OverflowX || OverflowY) {
style.overflowX = _.isBoolean(OverflowX) ? 'scroll' : OverflowX;
style.overflowY = _.isBoolean(OverflowY) ? 'scroll' : OverflowY;
}
if (Fit) {
style.minWidth = '0px';
style.minHeight = '0px';
style.width = '100%';
style.height = '100%';
}
if (P) {
style.padding = _.isNumber(P)
? `${P}px ${P}px ${P}px ${P}px`
: _.isArray(P)
? `${P[0]}px ${P[1]}px ${P[2]}px ${P[3]}px`
: `${P.x}px ${P.x}px ${P.y}px ${P.y}px`;
}
if (M) {
style.margin = _.isNumber(M)
? `${M}px ${M}px ${M}px ${M}px`
: _.isArray(M)
? `${M[0]}px ${M[1]}px ${M[2]}px ${M[3]}px`
: `${M.x}px ${M.x}px ${M.y}px ${M.y}px`;
}
return (
<div ref={ref} {...rest} style={style}>
{children}
</div>
);
},
);
Yes, i have the same question. can anyone mention the usecase of forwardRef that cant be achieved by sending refs as props? there must be a reason for introducing forwardRef
Have a look at this code https://codesandbox.io/s/snowy-feather-yrsjwn?file=/src/App.js
It is a simple example of both, passing ref as props as well as using forwardRef
@zmeyc ok, thx)