Как использовать useRef, когда элемент находится внутри условия? - PullRequest
1 голос
/ 27 сентября 2019

Проблема в том, что useRef запускается во время первого рендера.Два примера, когда это может быть проблемой.

  1. Когда может быть какая-то загрузка
const Problem1 = () => {  
 const ref = useRef();

 if (loading)    
     return null;

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

}
Когда ref находится внутри некоторого условия.
const Problem2 = () => {
 const ref = useRef();

 return user ? <input ref={ref} value={user.name} /> : <Exit >;

}

пример песочницы https://codesandbox.io/s/nifty-feynman-z68k0

Во втором случае я по крайней мере мог показать элемент в начале сдисплей: нет.Но как решить первую проблему, я понятия не имею.

Каковы лучшие практики в этих случаях?

1 Ответ

3 голосов
/ 27 сентября 2019

Проверьте, работает ли это для вас:

Из React DOCS: https://reactjs.org/docs/hooks-reference.html#useref

useRef ()

Однако useRef() полезен не только для атрибута ref.Это удобно для хранения любого изменяемого значения, похожего на то, как вы используете поля экземпляров в классах.

Это работает, потому что useRef () создает простой объект JavaScript.Единственная разница между useRef () и созданием объекта {current: ...} заключается в том, что useRef будет выдавать вам один и тот же объект ref при каждом рендеринге.

The useRef объект не будет меняться при рендерах.У вас всегда будет одна и та же ссылка для объекта useRef со свойством current.Что может измениться - это то, что вы храните внутри этого свойства current.

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"/>
...