useRef 활용법
September 07, 2020
UseRef의 current?
-
정의
- 컴포넌트 내에서 mutable한 객체를 만들어 사용 할 수 있다.
ref Object의 추가된 값은 current 키의 값으로 업데이트된다.
- mutable한 객체는 자바스크립트 Heap객체처럼 사용가능하다
- React는 상태가 변경되면 렌더링이 되고나서 상태의 값을 알 수 있기떄문에 불필요한 렌더링을 막을수 있다.
- 컴포넌트 안에서 조회 및 수정 할 수 있다(생명주기 포함)
- 리엑트는 변경상태를 감지하지 않는다.(값 - mutable object)이 변경되도 리렌더링 되지 않는다.)
-
사용법
-
DOM 선택
- input태그의 ref property에 넣으면 ref.current 객체안에 input에 대한 속성이 입력된다.
-
ref.current안에는 input에 대한 이벤트 / 속성이 있어 focus()같은 처리를 할 수 있다.
const Focus = () => { const InpuRef = useRef(); const getFocus = () => { InpuRef.current.focus(); } return( <> <button onClick={getFocus}>Focus</button> <input type="text" ref={InpuRef}/> </> ) }
-
클래스의 Instance filed 처럼 사용
- useRef()의 매개변수로 하나의 객체를 초기화해서 사용가능(current 키의 value)
- useRef()의 current 객체에 접근해서 언제든지 조회/수정/입력이 가능하다
- 리엑트는 이러한 ref객체의 변경을 감지하지 못한다.
- setTimeout, setInterval을 통해서 만들어진 id
- 외부 라이브러리를 사용하여 생성된 인스턴스(socket)
-
스크롤 위치에서 사용된다.
//setTimeout / setInterval 사용 function Timer() { const intervalRef = useRef(); useEffect(() => { const id = setInterval(() => { }); intervalRef.current = id; return () => { clearInterval(intervalRef.current); }; }); } // 외부 라이브러리 사용 const socket = useRef(); useEffect(() => { socket.current = io.connect("http://localhost:8000"); navigator.mediaDevices.getUserMedia({ video: true, audio: true }).then(stream => { setStream(stream); if (userVideo.current) { userVideo.current.srcObject = stream; } }) socket.current.on("yourID", (id) => { }) }, []);
-
-
주의사항
- 렌더링 중에 ref를 설정하면 사이드 이펙트 발생
-
useRef()의 initialState는 생성자를 호춣하면 매번 ref객체가 생김
function Image(props) { // ⚠️ 렌더링 마다 계속해서 생성 const ref = useRef(new IntersectionObserver(onIntersect)); } function Image(props) { const ref = useRef(null); // ✅ 한번만 생성 function getObserver() { if (ref.current === null) { ref.current = new IntersectionObserver(onIntersect); } return ref.current; } // 필요시 getObserver() 호출 }