For accessing the DOM node of an HTML element or referring a React element, we can utilize the ref
attribute. In React, we can utilize React.crateRef()
function or React.useRef()
hook for generating an object that has access to the referred DOM node. Several cases may be faced while we are developing React application.
1) Referring HTML Element.
class RefHtml extends React.Component {
constructor(props){
super(props);
this.textInput = React.createRef();
}
render() {
return (
<div>
<input type="text" ref={this.textInput} />
<button onClick={()=>{this.textInput.current.focus();}}>Focus</button>
</div>
);
}
}
2) Referring React Element (Class Component).
class ReferredElement extends React.Component {
constructor(props){
super(props);
this.state = {status: "inactive"};
}
setActiveState() {
this.setState({status: "active"});
}
render() {
return <div>Status: {this.state.status}</div>
}
}
class RefReact extends React.Component {
constructor(props) {
super(props);
this.childRef = React.createRef();
}
render() {
return (
<div>
<ReferredElement ref={this.childRef} />
<button onClick={()=>{this.childRef.current.setActiveState()}}>Run setActiveState</button>
</div>
)
}
}
3) Referring An Element In A Function Component. In this case, React.useRef()
hook is used.
function RefFunc() {
const textInputRef = React.useRef(null);
function focusToInput() {
if (textInput) {
textInputRef.current.focus();
}
}
return (<div>
<input type="text" ref={textInputRef} />
<button onClick={focusToInput}>Focus</button>
</div>);
}
4) Referring Using Callback Function.
class RefCallback extends React.Component {
constructor(props){
super(props);
this.textInputRef = null;
}
focusToInput() {
if (this.textInputRef) {
this.textInputRef.focus();
}
}
render() {
return (
<div>
<input ref={(elmnt)=>{this.textInputRef = elmnt;}} />
<button onClick={()=>{this.focusToInput();}}>Focus</button>
</div>
)
}
}
5) Referring An Element In Child Component Using Callback Function.
function RefCallbackChild(props) {
return (
<input type="text" ref={props.callbackRef} />
)
}
class RefCallbackParent extends React.Component {
constructor(props) {
super(props);
this.textInputRef = null;
}
render() {
return (
<div>
<RefCallbackChild callbackRef={(elmnt) => {this.textInputRef = elmnt}} />
<button onClick={()=>{this.textInputRef.focus();}}>Focus</button>
</div>
);
}
}
6) Forwarding Reference Into A Function Component Using ForwardRef. The React.forwardRef()
function can be used to forward the ref
value into a function component.
function CustomInputElement(props, ref) {
return (
<div>
<input ref={ref} />
<button>{props.children}</button>
</div>
)
}
const CustomInput = React.forwardRef(CustomInputElement);
class CustomInputParent extends React.Component {
constructor(props) {
super(props);
this.customInputRef = React.createRef();
}
render() {
return (
<div>
<button onClick={()=>{this.customInputRef.current.focus();}}>Focus</button>
<CustomInput ref={this.customInputRef}>Custom Input Button</CustomInput>
</div>
);
}
}
7) Forwarding Reference Into An Element Created By Higher-Order-Component Function. If we create an element by HOC function, reference will be consumed by wrapper component, not by the component which is wrapped. Take a look this following HOC function.
function hoc(WrappedComponent) {
class Wrapper extends React.Component {
render() {
return (
<WrappedComponent {...this.props} />
);
}
}
return Wrapper;
}
As we see, the result of the HOC function is another component which is the Wrapper
class. If we pass a reference, it cannot be directly accessed by the WrappedComponent
class. The React.forwardRef()
function can be used and modification of HOC function is required.
function hoc(WrappedComponent) {
class Wrapper extends React.Component {
render() {
const {forwardedRef, ...rest} = this.props;
return (
<WrappedComponent ref={forwardedRef} {...rest} />
);
}
}
function forwardedElement(props, ref) {
return (
<Wrapper {...props} forwardedRef={ref} />
);
}
return React.forwardRef(forwardedElement);
}
class WrappedInputElement extends React.Component {
constructor(props) {
super(props);
this.inputRef = createRef();
}
focusToInput() {
this.inputRef.current.focus();
}
render() {
return (
<input type="text" ref={this.inputRef} />
)
}
}
const WrappedInput = hoc(WrappedInputElement);
class WrappedInputParent extends React.Component {
constructor(props) {
super(props);
this.inputRef = React.createRef();
}
render() {
return (
<div>
<WrappedInput ref={this.inputRef} />
<button onClick={()=>{this.inputRef.current.focusToInput();}}>Focus</button>
</div>
)
}
}
Comments
Post a Comment