It might look like unnecessary in your example, where you only read the ref, but it becomes important and understandable, if you consider that you also want to set a value to the ref.
If the react-people would have implemented useRef without the .current, it actually would work if you never have to set the value (in runtime). But then you wouldn't need a ref at all. E.g. then your example could perfectly fine be written as just:
const myVar = 'Hello world!';
return <h1>{myVar}</h1>
But you always need to set some value to the ref, and that would just be not possible without the .current.
Here I show some examples to illustrate what would have happened, if the react-people would have done it without .current:
example 1: set myVar.current
e.g. consider this working example:
// in the first run of the component:
const myVar = useRef('old value'); // myVar === useRef_returnValue === { current: 'old value' }
myVar.current = 'new value'; // myVar === useRef_returnValue === { current: 'new value' }
// in the next run of the component:
// myVar is a reference to the same,
// now changed useRef_returnValue === { current: 'new value' }
const myVar = useRef('old value');
// (Note that 'old value' in useRef('old value') is only the initial value,
// which doesn't matter anymore after the first run.)
That would not work if it was without the .current:
// in the first run of the component:
let myVar = useRef('old value'); // myVar === useRef_returnValue === 'old value'
myVar = 'new value'; // myVar is a completely new string 'new value', no reference to the useRef_returnValue anymore.
// in the next run of the component:
// myVar is a reference to the same,
// unchanged useRef_returnValue, still with value 'old value'.
let myVar = useRef('old value');
example 2: ref-property
Even in cases where you might think you never want to set a value, e.g.:
const inputRef = useRef();
return <input ref={ inputRef } />; // input.ref becomes the internal useRef-object
the input component needs something it can attach itself to. E.g. a fictional implementation might look something like:
const input = function( props ){
const thisDomObject = thisDomObject();
if( props.ref ){
// input.ref.current becomes thisDomObject,
// input.ref is the internal useRef-object, so
// (useRef-object).current also becomes thisDomObject
props.ref.current = thisDomObject;
}
};
This would not work without the .current:
// input.ref was the internal useRef-object, and now becomes thisDomObject.
// The internal useRef-object stays unchanged.
props.ref = thisDomObject;
Remark:
I think the property name "current" is just a more or less arbitrarily choosen name that doesn't matter. The only important thing is, that it is a property.