개발자
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일
좋은 답변 감사드립니다. 지식이 짧으시다기에는 이해가 쏙쏙 되게 설명해주시는게 멋지십니다...
지금 가입하면 모든 질문의 답변을 볼 수 있어요!
현직자들의 명쾌한 답변을 얻을 수 있어요.
이미 회원이신가요?
지금 가입하면 모든 질문의 답변을 볼 수 있어요!