Skip to content

Instantly share code, notes, and snippets.

@jamesreggio
Last active January 8, 2023 21:40
Show Gist options
  • Save jamesreggio/142215754ad06f375bd87657c6227ed8 to your computer and use it in GitHub Desktop.
Save jamesreggio/142215754ad06f375bd87657c6227ed8 to your computer and use it in GitHub Desktop.
Simple example usage of React.forwardRef()
// 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();
}
}
@jonlepage
Copy link

jonlepage commented Dec 14, 2020

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>
		);
	},
);

@Kazerian
Copy link

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment