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() 호출
      }

© 2023, Customized by Joon