Jun 개발노트

useRef 활용법

September 07, 2020

UseRef의 current?

  1. 정의

    • 컴포넌트 내에서 mutable한 객체를 만들어 사용 할 수 있다.
    • ref Object의 추가된 값은 current 키의 값으로 업데이트된다.
    • mutable한 객체는 자바스크립트 Heap객체처럼 사용가능하다
    • React는 상태가 변경되면 렌더링이 되고나서 상태의 값을 알 수 있기떄문에 불필요한 렌더링을 막을수 있다.
    • 컴포넌트 안에서 조회 및 수정 할 수 있다(생명주기 포함)
    • 리엑트는 변경상태를 감지하지 않는다.(값 - mutable object)이 변경되도 리렌더링 되지 않는다.)
  2. 사용법

    1. 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}/>
         </>
        )
        }
    2. 클래스의 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) => {
        })
        }, []);
  3. 주의사항

    • 렌더링 중에 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() 호출
      } 

Written by Junho You 배운것을 기록하자