The problem is that useRef is triggered during first render. Two examples when it could be a problem.
- When one can have some loading
 
const Problem1 = () => {  
 const ref = useRef();
 if (loading)    
     return null;
 return <input ref={ref} value={} />;
}
- When ref is inside some condition.
 
const Problem2 = () => {
 const ref = useRef();
 return user ? <input ref={ref} value={user.name} /> : <Exit >;
}
sandbox example https://codesandbox.io/s/nifty-feynman-z68k0
In the second case I at least could show element at the beginning with display: none. But how to solve first problem I have no idea.
What are the best practices in these cases?
See if this works for you:
From React DOCS: https://reactjs.org/docs/hooks-reference.html#useref
useRef()
However, useRef() is useful for more than the ref attribute. It’s handy for keeping any mutable value around similar to how you’d use instance fields in classes.
This works because useRef() creates a plain JavaScript object. The only difference between useRef() and creating a {current: ...} object yourself is that useRef will give you the same ref object on every render.
The useRef object won't change across renders. You'll always have the same reference for the useRef object with a current property. What may change is what you are keeping inside that current property.
function App() {
  const input1_ref = React.useRef(null);
  const input2_ref = React.useRef(null);
  const [showInput2, setShowInput2] = React.useState(false);
  
  React.useEffect(()=>{
    input1_ref.current ?
      console.log('Input1 has been mounted...')
    : console.log('Input1 has NOT been mounted...');
    input2_ref.current ?
      console.log('Input2 has been mounted...')
    : console.log('Input2 has NOT been mounted...');
  });
  
  return(
    <React.Fragment>
      <div>Input 1</div>
      <input type='text' ref={input1_ref}/>
      {showInput2 &&
        <React.Fragment>
          <div>Input 2</div>
          <input type='text' ref={input2_ref}/>
        </React.Fragment>
      }
      <div>
        <button onClick={()=>setShowInput2((prevState)=>!prevState)}>Click</button>
      </div>
    </React.Fragment>
  );
}
ReactDOM.render(<App/>, document.getElementById('root'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.3/umd/react-dom.production.min.js"></script>
<div id="root"/>
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