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
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.
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>
);
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With