Refs Part 2


In our last article, we have seen how do we apply reference to an element. Remember that element can be a HTML element or custom react element. Remember that all the reference objects we have created were for HTML elements, but we can pass the reference to a Custom React Elements as well provided they are Class Components.

Lets Open index.js file from our demo-project.

Now assuming that we are developing an application for an Elevator Manufacturing Company. Lets say we have to develop two components as part of doing the application development. One is Elevator Component and Summary Component. I have the Code handy and pasting it here

class Elevator extends React.Component{

  constructor(props){

    super(props);

    this.elevatorRef=React.createRef();

  }



  render(){

    return(

      <div>

        <h2>Welcome to Elevator Ordering Screen...</h2>

        <p>

          <label>Elevator Name : <input ref={this.elevatorRef} type="text"></input></label>

        </p>

        <p>

          <label>Elevator Speed : <input type="text"></input></label>

        </p>

        <p>

          <label>Elevator Load : <input type="text"></input></label>

        </p>

        <Summary></Summary>

        

      </div>

    );

  }

}





class Summary extends React.Component{

  constructor(props){

    super(props);

  }



  render(){

    return (

      <div>

        <h2>Summary Details...</h2>

        <p>

          <label>Elevator Name : <b>Name - 1</b></label>

          

        </p>

        <p>

          <label>Elevator Speed : <b>10 m/s</b></label>

        </p>

        <p>

          <label>Elevator Load : <b>550 Kg</b></label>

        </p>

      </div>

    );

  }

}



const element=<Elevator></Elevator>

ReactDOM.render(element,document.getElementById("root"));

Now customer has a requirement that when we click on a given field, focus should go back to the respective textbox. 

So now when user Clicks on Elevator Name in  Summary Component, focus should go back to Elevator Name textbox in the Elevator Component. For doing that we have to access the reference of our Elevator Component input element in our Summary Component. This technique is Called as Forwarding refs. 

Ref forwarding is a technique for automatically passing a ref through a component to one of its children.

Now we will pass the reference to summary component from Elevator Component. I give the property name as elevatorRef and to this we will pass our elevator name input element reference. 

Lets trigger onClick event on our paragraph tag in our Summary component. Lets call a function called as focusElevatorName.

Now lets implement this function. With in this function, lets access the reference using the properties and we can call the focus method.

Until now we have seen how to use refs in Class Component. Now lets see how can we handle refs in function components.

I have a testComponent function handy and pasting it here. 

function testComponent(){

  function handleClick() {
  }

  return (

    <div>

      <input type="text" />

      <input type="button" value="Focus the text input" onClick={handleClick}/>

    </div>

  );

}

Now lets declare a Variable and assign it to null. Call the focus method on that variable inside handleClick function. 

Now assign the input element to that variable we have created using ref. But here if we observe, we are using a Callback.

Now Call this function component and render it to our root container.

Save these changes, navigate to the browser. On Click of the button we can see that textbox is focused.

We have seen how do we use ref for an input element inside a function Component. Remember that we can,  use the ref attribute inside a function component as long as you refer to a DOM element or a class component.

Refs cannot be attached to function components that is because function components do not have instances so you can’t reference them.

If we want to allow people to take a ref to our function component, you can use forwardRef method in React, or you can convert the component to a class.

Lets create a demo Function Component using React. forwardRef

Method and we will pass an arrow function and this function can receive the properties which will be passed to this component as one parameter and the ref as another parameter. 

Lets return a button from this Component. Now call a function on Click of this button and we will implement this function. 

With in this function, we will call the focus method using the reference which is being passed. 

Now lets call this function component from our Elevator Component.

Now call this Elevator Component and render it to our root container. 

Save these changes, navigate to the browser. Click on the button, we can see that the elevator name textbox is focused. 

import ReactDOM from "react-dom";

import React, { Component } from "react";



const DemoComponent=React.forwardRef((props,ref)=>{

  function testClick(){

    ref.current.focus();

  }

  return(

    <button onClick={testClick}>Click</button>

  )

});



class Elevator extends React.Component{

  constructor(props){

    super(props);

    this.elevatorRef=React.createRef();

  }



  render(){

    return(

      <div>

        <h2>Welcome to Elevator Ordering Screen...</h2>

        <p>

          <label>Elevator Name : <input ref={this.elevatorRef} type="text"></input></label>

        </p>

        <p>

          <label>Elevator Speed : <input type="text"></input></label>

        </p>

        <p>

          <label>Elevator Load : <input type="text"></input></label>

        </p>

        <Summary innerRef={this.elevatorRef}></Summary>

        <DemoComponent ref={this.elevatorRef}></DemoComponent>

      </div>

    );

  }

}



class Summary extends React.Component{

  constructor(props){

    super(props);

  }

  

  focusInput=()=>{

    this.props.innerRef.current.focus();

  }

  render(){

    return (

      <div>

        <h2>Summary Details...</h2>

        <p onClick={this.focusInput}>

          <label>Elevator Name : <b>Name - 1</b></label>          

        </p>

        <p>

          <label>Elevator Speed : <b>10 m/s</b></label>

        </p>

        <p>

          <label>Elevator Load : <b>550 Kg</b></label>

        </p>

      </div>

    );

  }

}



function testComponent(){

  

  let testRef=null;

  function handleClick() {

    testRef.focus();

  }



  return (

    <div>

      <input type="text" ref={e=>testRef=e} />

      <input type="button" value="Focus the text input" onClick={handleClick}/>

    </div>

  );

}

const element=<Elevator></Elevator>

ReactDOM.render(element,document.getElementById("root"));

Video Reference:





© 2020 Pragimtech. All Rights Reserved.