Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use useRef when element is inside condition?

The problem is that useRef is triggered during first render. Two examples when it could be a problem.

  1. When one can have some loading
const Problem1 = () => {  
 const ref = useRef();

 if (loading)    
     return null;

 return <input ref={ref} value={} />;

}
  1. 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?

like image 634
Sergey Filatov Avatar asked Nov 01 '25 05:11

Sergey Filatov


1 Answers

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"/>
like image 51
cbdeveloper Avatar answered Nov 03 '25 01:11

cbdeveloper



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!