개발자

Next.js App router + recoil 적용 방법에 질문이있습니다.

2024년 01월 18일조회 654

next.js 에 recoil 을 적용하려하니 RecoilRoot 컴포넌트로 감싸줘야하는 부분에서 어려움이 생겼습니다. RecoilRoot 는 react.createContext를 쓰기에 클라이언트 컴포넌트에서 사용해야 한다는 것인데 이를 위해 RecoilRoot만을 return 하는 클라이언트 컴포넌트를 만들고 root layout 에서 불러와 그것으로 children을 감싸주면 된다는 것이였습니다. https://velog.io/@pakxe/Next.js-Recoil%EC%9D%84-Next.js-%EC%97%90%EC%84%9C-%EC%82%AC%EC%9A%A9%ED%95%98%EB%8A%94-%EB%B0%A9%EB%B2%95%EC%97%90-%EB%8C%80%ED%95%9C-%EA%B3%A0%EC%B0%B0%EA%B3%BC-children-prop-pattern 위 블로그의 마지막 하단을 보면 ``` // ./app/layout.tsx // 보이는 코드 <RecoilRoot> {children} </RecoilRoot> // 실제 코드 <RecoilRoot children={<Home/>}/> ``` 처럼 동작하기에 RecoilRoot 클라이언트 컴포넌트 하위에 서버 컴포넌트 들이 들어가는게 아니라 RecoilRoot 와 chilren 이 같은 부모를 두고 서로 부모자식 관계가 아니니 클라이언트 컴포넌트 하위에 서버 컴포넌트가 들어가는 것이 아니다 라고 하는데 이 부분이 이해하기 어려워서요... 실제코드 부분을 보면 RecolRoot 가 children 이라는 컴포넌트를 파라미터로 받기에 파라미터로 받는 과정에서 이미 렌더링이 되어 넘어가기에 Recoil Root는 서버 컴포넌트인 children이 렌더링된 상태에서 파라미터로 받아 서버 컴포넌트가 클라이언트 컴포넌트 하위에서 렌더링 되는 것이 아니다.. 가 맞는 것인지 궁금합니다.

이 질문이 도움이 되었나요?
'추천해요' 버튼을 누르면 좋은 질문이 더 많은 사람에게 노출될 수 있어요. '보충이 필요해요' 버튼을 누르면 질문자에게 질문 내용 보충을 요청하는 알림이 가요.

답변 2

인기 답변

유길종님의 프로필 사진

사실 use client로 래핑해야하는 이유는 굳이 라이브러리 코드를 까보지 않더라도 쉽게 예상할 수 있습니다. next.js의 docs를 보면 알 수 있는 사실들을 정리하면 다음과 같습니다 1. 서버컴포넌트에서는 이벤트핸들러와 리액트 훅을 사용할 수 없다. 2. 클라이언트 컴포넌트는 서버 컴포넌트를 직접적인 자식으로 가질 수 없다 3. 하지만 클라이언트 컴포넌트는 일종의 “슬롯”을 열어두는 개념으로 children을 두는 것을 통해 서버컴포넌트를 자식으로 렌더링 할 수 있다. 중요한것은 직접적으로 클라이언트 컴포넌트가 서버컴포넌트를 임포트해서 특정 서버컴포넌트를 자식으로 사용하는 것과 같은 행동에 제약이 있다는 것이며 RSC의 구현을 알면 이런 제약이 있는 이유에 대하여 더욱 이해가 쉬울 수 있지만 그냥 이렇게하면 된다정도로만 인지해도 사용하는데 문제는 없습니다. 이제 리액트의 개념으로 넘어가보면 children이라는 것은 일반적으로 ReactNode 타입을 가지게 되는 특별한 props입니다. children은 컴포넌트 일수도 있고 / 숫자일수도 있으며 / 문자열일수도 있고 / 함수일수도있습니다. 그러니 우선 children이라는 컴포넌트를 이라는 문장은 조금 어색한 점이 있는 것 같아요 컴포넌트가 아닌 children도 있으니까요 그리고 이러한 children을 통하여 리액트는 컴포넌트간의 composition을 구현하며 각 컴포넌트 간의 결합도를 느슨하게 만들어줍니다. 아까 위에서 잠깐 이야기한 슬롯의 개념은 여기에서 사용되며 composition을 통해 children으로 들어오는 값이 서버컴포넌트의 렌더링 결과물이든 / 클라이언트컴포넌트이든 / 숫자이든 children이라는 슬롯을 열어둔 클라이언트컴포넌트의 입장에선 children이 위치한 곳에 children을 위치시킨다는 책임만 수행하기 때문에 위와 같은 행위가 가능해집니다. 이제 여기까지 생각을 했다면 왜 클라이언트컴포넌트에서 서버컴포넌트를 임포트할 수 없는지도 생각할 수 있습니다. 1. 서버컴포넌트의 내용물에는 서버에서만 실행될 수 있는 코드가 들어가있을 수 있다. 2. 클라이언트컴포넌트 측에서 서버컴포넌트의 정보를 알고 / 서버컴포넌트를 실행시킬 수 있는 권한을 주는 경우에는 3. 서버컴포넌트에 들어가있을 수 있는 서버에서만 실행가능한 코드를 클라이언트에서 실행하려고 시도할것이며 만약 서버코드가 있다면 그런 시도는 당연히 실패합니다. 그러니까 클라이언트컴포넌트는 서버컴포넌트를 직접적으로 알면 안되는 것이죠 제 지식이 짧아 잘 모르겠지만 저 글에서 주장하는바와 같이 children도 prop이니 부모자식이 아니라 형제라고 생각한다면 리액트에서 컴포넌트간의 부모자식 관계를 표현할 수 있는 방법이 있는지는 모르겠네요 마지막으로 이와 같은 내용들은 오독하기 쉽다보니 개인의 블로그보다는 공식적인 메인테이너의 블로그 혹은 docs들을 참조하시면서 학습하시는 것을 추천드립니다

세혁님의 프로필 사진

세혁

작성자

삼성 청년 SW 아카데미 웹 개발2024년 02월 14일

좋은 답변 감사드립니다. 지식이 짧으시다기에는 이해가 쏙쏙 되게 설명해주시는게 멋지십니다...

허니님의 프로필 사진

클라이언트 컴포넌트에서 서버 컴포넌트를 가져오는 것은 되지 않지만, 중첩은 가능합니다. 말씀하신 대로 렌더링되어 넘어가기 때문입니다. 블로그 글의 "부모자식 관계" "하위에 들어가는 것이 아니다"는 관점의 차이인 것 같습니다.

지금 가입하면 모든 질문의 답변을 볼 수 있어요!

현직자들의 명쾌한 답변을 얻을 수 있어요.

또는

이미 회원이신가요?

목록으로
키워드로 질문 모아보기

실무, 커리어 고민이 있다면

새로운 질문 올리기

지금 가입하면 모든 질문의 답변을 볼 수 있어요!