useRef - current null 문제

Gee·2022년 12월 15일
1

netflix-clone 프로젝트에서 carousel을 라이브러리써서 만들었는데, 생각보다 커스텀이 어려워서 마음에 들지않았다. 이번에 시간이 생겨서 직접 구현하는 도중 useRef - current null 문제에 직면하게 되었고, 해당 문제를 해결하며 useRef의 특성을 알게되었다. 그 과정을 적을 것이다.

문제상황 🧐

각 카드의 width를 받아와서 부모 컴포넌트(CarouselTwo)에서 계산을 해주기위해서 ref 요소를 context api를 통해 공유하는 상황이다.

CardItem 컴포넌트에서 부모컴포넌트에서 받아온 ref를 지정해주고 data가 들어왔을 때 ref 값이 바뀌어있겠지..? 생각하고 console.log를 찍어보았는데

const CardItem: React.FC<SliderItemProps> = ({ movie, ...props }) => {
  const context = React.useContext<Partial<SliderContextProps>>(SliderContext);
  const { elementRef } = context;  
  console.log(elementRef) // current: null 
  console.log(context) // elementRef : current : ~~~
  
  return (
    <CardItemContainer ref={elementRef} {...props}>
      <img src={`${TMDB_BASE_IMG_URL}${movie.backdrop_path}`} alt={movie.name}/>
    </CardItemContainer>
  )
}

이상하게도 context의 elementRef에 접근해서 console을 찍으면 null이고, context로 접근했을 때는 해당 div태그 요소를 받아왔다.

해결과정

useRef의 특징중에 아래의 두가지 특징이 있다.
1. Ref가 변해도 re-render 되지않는다.
2. re-render되어도 Ref는 유지된다.

DOM 요소에 접근만 하면된다고 생각하고 두가지 특징을 잊고 있었다..!
그럼, data가 들어와서 다시 re-render 될 때 ref는 data가 들어오기 전에 null인 값을 갖고 있기때문에 변경이 되지 않는 것이다..

그래서 위의 CardItem의 부모 컴포넌트의 조건문을 변경하였다.
Before

    <>
    <CarouselTwo>
      {loading ? <>로딩중..</> : 
      movieData.results.map((movie: MovieDataProps) => (
        <CardItem movie={movie} key={movie.id}/>
        )
        )}
    </CarouselTwo>
    </>

After
데이터가 있을 때 CardItem을 render하게끔 수정

    <div>
    {loading && !movieData?.results.length ? 
      <>로딩중</>
      :
    <CarouselTwo>
      {
        movieData.results.map((movie: MovieDataProps) => (
          <CardItem movie={movie} key={movie.id}/>
          )
          )
        }
    </CarouselTwo>
      }
      </div>

회고 😃

useRef의 개념만 이해를 하고, 직접 코드로 hook을 사용하여 구현을 많이 하지 못했었는데 이번 기회를 통해서 개념적으로 알던 것들을 직접 구현하고 문제에 직면하면서 해결할 수 있어서 좋았습니다 : )

참고문서

https://stackoverflow.com/questions/56541342/react-hooks-why-is-current-null-for-useref-hook

profile
작은 실패, 빠른 피드백, 다시 시도

0개의 댓글