REACT

useRef

gurwhddl 2023. 4. 7. 20:33

기존 JS에서 querySelector 같은걸로 접근하는 것처럼 실제 DOM 요소에 접근할 때 씀

const ref = useRef()
<input id="ID" ref={ref} /> 

console.log(ref) // {current : <input#ID>}

useRef()로 객체를 생성해서 원하는 DOM에 넣어주면 ref.current가 해당 DOM을 가리킴

but DOM을 직접 조작하거나 하는일은 안하는게 좋음(그거 안하려고 react 쓰는건데)

보통 focus를 둔다거나, reset 기능같은 것만 구현할 때 쓰는 게 일반적임

 

or

const intervalId = useRef(0)
const [count,setCount] = useState(0)
const id = 0
console.log(intervalId,count,id)
const startCounter = () => {
	id ++
    intervalId.current = setInterval(
      () => setCount((count) => count + 1),
      1000
    );
  };
  //버튼 클릭했을 때 startCounter가 실행됨

startCounter 함수가 실행될때마다 재렌더링이 일어나면서 count의 값은 1씩 증가하고 , 그냥 변수로 설정해놓은 id는 1이고 ,

intervalId의 current 값에는 setInterval의 id값이 계속 보존되고 있음 

ref는 재렌더링을 해주진 않음 but 반환된 객체는 컴포넌트의 전 생애주기를 통해 유지됨(by react 공식문서)

왜냐 ? ref는 그냥 일반적인 JS에서 객체 저장하는 것처럼 heap 영역에 저장되는 일반적인 자바스크립트 객체임

그래서 값을 바꿔도 기존 메모리 주소를 참조하고 있음 

-한마디로 react에서 이 값이 바뀐지를 모르고 있으니 재렌더링도 못한다는 소리 

 

그래서 저렇게 setInterval이나 Timeout의 id값을 ref로 저장해놓으면 나중에 clear 할 때 편함

*물론 버튼 여러번 눌러버리면 Interval이 여러번 등록되어버려서 intervalId의 값으로는 종료가 안되는 상황이 생김

 

*setTimeout,setInterval은 실행되자마자 콜백함수 넘겨주고 id값을 리턴하면서 종료됨 - 이 id값은 해당 타이머를 종료시킬 때 필요

 

보통 state로 관리하는 걸 제어 컴포넌트 , ref로 관리하는 걸 비제어 컴포넌트라고 한다고 함 (물론 더 복잡한게 있긴함)

input에 입력받는 상황에서

제어 컴포넌트를 쓰게 되면

- 데이터와 UI에서 입력한 값이 항상 동기화됨 - input onChange 생각해보면 됨

- 실시간으로 입력값을 검사하는 등의 행동이 가능하겠지만, 입력할때마다 재렌더링 되기 때문에 이게 싫으면 다른 조치를 취해야됨