[Issue] React.forwardRef

young_pallete·2021년 7월 21일
0

Issues

목록 보기
3/6

시작하며 🍭

역시 오늘도 디버깅과 싸우며...
1시간의 삽질 끝에, 역시 오늘도 리액트님께 한수 배웠습니다. 😂

오늘의 오류는 다음과 같았어요.
무한스크롤을 하려 intersection Observer API를 사용하려 했는데, 다음과 같은 오류가 떴습니다!

이 아이가... 제게 왜 이러는 걸까요... 🤣
그렇게 시작된 삽질!

본론 📃

1차 해결 - forwardRef()

제 코드는 원래 다음과 같았습니다.
해당 컨테이너를 ref로 해서 observe를 위한 element를 가져오려 했는데, 위와 같은 오류가 나왔습니다!

const DiaryCards = ({ diaries, diariesError }, ref) => {
    const diaryCards = useRef(null);
    if (diariesError) return <StyledDiaryCards> 일기를 불러오는 데 에러가 발생했어요! 😓</StyledDiaryCards>
    return (
        <StyledDiaryCards ref={diaryCards}>
            {diaries && diaries.map(diary => {
                return (
                    <StyledDiaryCardContainer key={diary._id}>
                        <DiaryCard key={diary._id} diary={diary}/>
                    </StyledDiaryCardContainer>
                )
            })}
        </StyledDiaryCards>
    );
};

오류가 워낙 많이 떠서, 계속해서 뭐가 문제인지 하나씩 헤쳐나가다 보니, 저 경고 문구가 보이더라구요.

ResponsiveWrapper를 확인하세요!

왜 갑자기 저걸 확인하라지? 하면서 갸우뚱하다가 딱 뇌리에 스친 게,
제가 저 컴포넌트의 style을 덮어썼던 것을 기억했습니다.

const StyledDiaryCards = styled(ResponsiveWrapper)`
    display: flex;
    /* justify-content: flex-start; */
    margin-top: 3rem;
    flex-flow: wrap;
    ${({ theme }) => css`
        background: ${theme.bgColor};
    `}
`;

이렇게 말이죠.

따라서 refforwardRef로 전달해라...? 정도로 가설을 세우게 됐습니다!
아무래도, 리액트에서 ref는 직접적으로 전달할 수 없기 때문이죠. 이때는 부모 컴포넌트에서 자식 컴포넌트를 참조하는 forwardRef를 사용하면 됩니다!

혹시 이 부분이 틀렸다면, 적극적인 비판해주신다면 감사합니다 😘!

그래서 실낱같은 기대를 가지며... 다음과 같이 refResponsiveWrapper에서 전달해주게 됐어요!

const ResponsiveWrapper = ({ children, ...rest }) => {
    const ref = useRef(null);
    return (
        <StyledResponsive { ...rest } ref={ref}>
            { children }
        </StyledResponsive>
    );
};

그리고 DiaryCards 컴포넌트도 다음과 같이 씌워주고!

export default React.forwardRef(DiaryCards);

ref를 집어넣어줬네요.

const DiaryCards = ({ diaries, diariesError }, ref) => {
    return (
        <StyledDiaryCards ref={ref}>
        	...

결과적으로! 제 부족한 실력에 수많은 경고들이 뜨지만 (...) 기존 ref에 관한 에러는 없이 의도된 대로 동작합니다!

2차 해결 - styled-component

그런데... 콘솔로 확인차 ref.current를 찍어보니 다음과 같이 오류가 또 발생하게 됩니다.

이제는 forwardRef를 해결했으니, 여지없이 styled-component에서 오류가 났다고 생각했어요. 그래서 생각해 보니...

왜 스타일이 아닌 엘리먼트를 저렇게 넘겨받았지...?

아니나 다를까, styledResponsiveWrapper을 넘겨받으려 했는데, 알고 보니 엘리먼트를 직접 넘겨받았...

결국 forwardRef까지 다 지우고... 변경했던 것들 지우고... 동작하니

휴... 결국 동작하네요 🤣

마치며 🖐🏻

  • 결론 1.
    뭔가 ref를 잘못 전달한 상황이 발생하면 forwardRef를 의심해봐라!
  • 결론 2.
    그래도 뭔가 current가 엘리먼트를 참조하지 않는다면, 그땐 내부 로직을 의심해봐라!

그냥 무심코 style을 갖다 쓰는 용도로 자주 애용했던 styled-component인데, ref 이슈가 생길 줄은 미처 생각도 못했어요. 물론 제가 직접 엘리먼트를 끌고 와서 문제가 발생한 거였지만요...🥺

이게 끝나는 대로, 갑자기 궁금한 게 생겼어요.

styled-component은 리액트를 통해 css를 어떻게 구현할까?

입니다. 아무래도 리액트와 styled-componet의 관계도 좀 많이 궁금하기도 하구요. 얼른 플젝 끝내고! 포스팅 해봐야겠습니다.

그럼, 이 글을 보시는 비슷한 경험의 분들께서는 저와 같은 삽질(?)을 하지 않기를 바라며! 😉

profile
People are scared of falling to the bottom but born from there. What they've lost is nth. 😉

0개의 댓글