본문 바로가기
스터디/2024 - 리액트 스터디

숙제 3. useRef 만들기

by 1005ptr 2024. 7. 6.
반응형

요구사항

  • useRef는 렌더링에 필요하지 않은 값을 참조할 수 있는 React Hook 입니다.
  • initialValue : 초기값
    • 변수에 담기는 초기값
    • 초기 렌더링 이후에는 무시되어야 함.
  • ref : { current: 현재값 } 구조를 담고 있음
    • current는 현재 ref가 가리키는 값을 나타낸다.
    • ref의 current는 변경 가능하다. mutable 하다.
/// ref : { current : any }
const ref = useRef(initialValue)

용례 1. 렌더링과 상관없는 변수 담는 통으로 쓰기

  • 진짜 그냥 통으로 쓰면 된다.

용례 2. 렌더링 엘리먼트에 ref로 등록하기

  • 컴포넌트의 기본 props로 ref 값이 있는지 체크하고 값이 있으면 내 현재 DOM 객체를 current에 등록시킨다.
  • 매번 render 함수가 호출 시 마다 등록하도록 하면 될듯

구현

  • 구현 자체는 매우 단순하다.
    function useRef(initialValue) {
      if(!hooks[index]){
          const ref = { current: initialValue };
          hooks[index] = ref;
      }
      const ref = hooks[index];
      index++;
      return ref;
    }

질문

주의사항
  • 초기화를 제외하고는 렌더링 중에 ref.current를 쓰거나 읽지 마세요. 이렇게 하면 컴포넌트의 동작을 예측할 수 없게 됩니다.
    • 예제를 보면 다 이벤트에서 사용하고 있다.
    • 렌더 함수 내에서 바로 쓰면 안되는 듯 왜 안되는지는 찾아보기
      • 리액트는 렌더링을 순수 함수로 유지하고 싶어하는데 current가 바뀌면 순수하지 않게 된다. -> 결과가 달라질 수 있음
    • Hook으로 치면 Hook에서 바로 쓰지말고 어디 다른데 안에서 써라는거 같음
      • useEffect나~ 이벤트에서 쓸 수 있다.
    • 렌더링 중에 무언가를 읽거나 써야 한다면 state를 써야 한다고 함
  • Strict Mode에서 React는 컴포넌트 함수를 두 번 호출하여 의도하지 않은 변경을 찾을 수 있도록 돕습니다. 이는 개발 환경 전용 동작이며 Production 환경에는 영향을 미치지 않습니다. 각 ref 객체는 두 번 생성되고 그중 하나는 버려집니다. 컴포넌트 함수가 순수하다면(그래야만 합니다), 컴포넌트의 로직에 영향을 미치지 않습니다.
    • #TODO useRef를 잘못 썼을때 Strict Mode에서 어떤 문제가 발생할까?
문제 해결
  • 커스텀 컴포넌트 내부의 DOM 에 달아놓은 ref를 외부에 던져주고 싶을때?
  • 컴포넌트를 forwardRef로 감싸면 커스텀 컴포넌트 단위로 ref를 밖에 던져 줄 수 있다.
  • 하나만 던져줄 수 있기 때문에 복잡한 컴포넌트에는 쓰면 안될 듯
    • 의미가 직관적이지 않기 때문에
  • Atomic 한 커스텀 컴포넌트에만 사용하면 좋을 듯

useRef 타입스크립트 반환 타입 관련

https://driip.me/7126d5d5-1937-44a8-98ed-f9065a7c35b5

  • MutableRefObject와 RefObject(Immutable)
  • 왜 컴포넌트에는 Immutable한 RefObject를 쓰도록 했는가?
    • 리액트에서 관리하기 때문
반응형

댓글