Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

When to use inputRef.current instead of this.inputRef React.js?

I am puzzled between two syntaxes to access references from the react documentation...All i want to know is when to use inputRef.current to access a reference instead of this.inputRef in react

like image 605
mr debug Avatar asked Mar 05 '23 12:03

mr debug


2 Answers

As other answers mention, current ref property is created by React.createRef(), which wasn't originally available in React 16 and was introduced in React 16.3.

Generally it is old syntax (React 15, React 16.0 to 16.2):

<input ref={ref => this.inputRef = ref}/>
...
this.inputRef.focus()

vs. new syntax (React 16.3 and higher):

inputRef = React.createRef();
...
<input ref={this.inputRef}/>
...
this.inputRef.current.focus()

New syntax introduces a usable pattern which can be used in older React versions as well:

inputRef = { current: null };
...
<input ref={ref => this.inputRef.current = ref}/>
...
this.inputRef.current.focus()

The important difference is that React.createRef() creates ref object that contains the only property, current. This is a pattern to keep ref object reference permanent, even if a ref in current property is changing. This way ref object can be passed by reference, even when current is initially null.

This previously was an antipattern, primarily because a ref is volatile:

const ComponentThatAcceptsRefs = ({ inputRef }) => (
  <button onClick={() => inputRef.focus() }>Focus</button>
);

and

<input ref={ref => this.inputRef = ref}/>
<ComponentThatAcceptsRefs inputRef={this.inputRef}/>

In this case it's undefined at the moment when it's passed as a prop. This would require to make inputRef prop a getter function to make it work, getInputRef={() => this.inputRef}.

While the same thing is possible with ref object (a demo):

const ComponentThatAcceptsRefs = ({ inputRef }) => (
  <button onClick={() => inputRef.current.focus() }>Focus</button>
);

and

inputRef = React.createRef();
...
<input ref={this.inputRef}/>
<ComponentThatAcceptsRefs inputRef={this.inputRef}/>

There may be more conventional and practical ways in React that don't rely on refs, yet it's possible to do that with ref object.

like image 150
Estus Flask Avatar answered Apr 05 '23 20:04

Estus Flask


When the reference is created using React.creatRef() a React 16 syntax then you can access it using current property of reference i.e inputRef.current.

React.createRef()

class User extends Component{
    constructor(props){
        super();
        this.nameField = React.createRef();
        this.onClick = this.focusOnNameField.bind(this);
        this.state = {
            name : props.name
        };

    }
    focusOnNameField = ()=>{
        this.nameField.current.focus();
    }

    render(){
        return(
            <div>
                <input ref={this.nameField} name="username" value={this.state.name} />
                <button onClick={this.onClick} >Fous on field</button>
            </div>
        )
    }
}

Without React.createRef()

const User = (props)=>{
    let nameField = null;


   const setRefernce = (inputElement)=>{

        this.nameField = inputElement;
    }
    const onClick = (e)=>{
        e.preventDefault();
        this.nameField.focus();
    }



    return(
        <div>
            <form onSubmit={onClick.bind(this)}>
                <input ref={setRefernce} name="username" value={props.name} />
                <button type="submit" >Focus Input</button>
            </form>

        </div>
    );
}
like image 20
Faisal Naseer Avatar answered Apr 05 '23 22:04

Faisal Naseer