안녕하세요, 질문드립니다. nextjs + apollo client로 프로젝트 구성중인데...
# 질문
y
안녕하세요, 질문드립니다. nextjs + apollo client로 프로젝트 구성중인데요, api 호출 시 서버 사이드 단 (getServerSideProps)에서 한번, 또 컴포넌트 단에서 한 번, 해서 두번 동일한 쿼리를 호출해야 하는 상황이 발생하더라구요. vue-apollo 에서는 한 코드로 서버/클라이언트를 모두 관리가 가능했는데, nextjs 에서는 관리 포인트가 괜히 많이지는듯한 느낌이 들어서요... 이를 한번에 해결할 수 있는 방법이 있을까요?
t
저도 이거 궁금하네요 ㅋㅋ 이전에는 _app.ts에서 getInitialProps로 getDataFromTree 때리고 cache를 말아줬었는데... getServerSideProps의 approach를 보면 요 방법이 좋은 방법은 아닌거같구요.
👍 1
y
앗 지혁님 아실줄 알았는데 ㅋㅋㅋ Vue 하다가 Nextjs로 넘어왔는데 아직 잘 몰라서 넘 슬픕니다 ㅋㅋㅋ
If you're using Next.js 9.3 or newer, we recommend that you use getStaticProps or getServerSideProps instead of getInitialProps.
곶통받는 중입니다....ㅋㅋㅋ
u
해당 의문을 들게한 코드 작성자입니다. ㅎㅎ.... api 호출을 두번 때린다기 보단, 아폴로 캐시 스토어에 하이드레이션된 데이터를 사용하기위한 코드가 컴포넌트단에 한번 더 들어갑니당. 네트워크 콜 자체는 한번해용!
ohh 1
y
네, 약간 오해가 있게 썼네요
두번 동일한 쿼리를 호출
->
두번 동일한 쿼리를 작성
으로 정정합니다 (_ _)
t
또이잉... 두번 작성해야되나요?? Apollo는 getDataFromTree 하면 안되나요? 저는 Relay 쓰다보니 두번 작성하는 문제는 없던거같네요 ㅠ
👀 1
u
현재 위 코드와 같은 방식으로
getServerSideProps
에서 네트워크 콜 후에 해당 데이터를 아폴로 캐시에 하이드레이션 시키고 컴포넌트에서 같은 쿼리를 호출해서 캐시스토어의 데이터를 사용하는 식이에용~
getServerSideProps
api 자체가 서버사이드에서만 실행되다보니 CSR에서 네트워크콜을 위한 쿼리도 필요하긴 한 상황입니다 🙂
t
• `getInitialProps`: 맨 처음 SSR 당시에만 실행됨 • `getServerSideProps`: path 이동시에 자동으로 Next.js에서 서버에 요청을 날리고 `getServerSideProps`의 응답을 페이지 컴포넌트의 Props로 자동으로 넣어줌 요 차이 맞죠?? 그러면 `getServerSideProps`를 썼을때 CSR에서 데이터 페칭을 하는 패턴이 맞나 싶어서요 ㅋㅋ
h
또이잉... 두번 작성해야되나요?? Apollo는 getDataFromTree 하면 안되나요?
아뇨 ㄱ냥 문서대로 쓰면 돼용 https://www.apollographql.com/docs/react/performance/server-side-rendering/#executing-queries-with-getdatafromtree
getServerSideProps 에 의존하실 필요가 없을텐데
preloading/prefetching 때문에 그러시는거면 다른 걸로 해결하셔야할듯
뭔가 끔찍한 솔루션인데
위에 올리신 코드에서 쿼리 두번쓰는 부분만 getDataFromTree 로 갈아끼울수 있겠네요
근데 integration 방법이 참... 뭐랄까
저거 CM-safe 한가 이건 의미가 없군요 apollo client 가 통째로 CM incompatible 하니
u
https://graphql-korea.slack.com/archives/CN13FD736/p1610517370249900?thread_ts=1610516011.247500&cid=CN13FD736 우선 지혁님 답변에 대해서 생각해봤는데,
gerServerSideProps
에서 데이터페칭한 응답을 컴포넌트에 주입하는 식으로 하고, 데이터 페칭을 위한 인풋이 인터랙션으로 바뀌는경우 url 패스를 변경하는 식으로 하면, 클라이언트 사이드에서 쿼리를 중복으로 작성하는 일을 없앨 수 있을 것 같습니당. 현재 고민은 이런방식으로 했을 때, 클라이언트 사이드에서의 뮤테이션 이후의 캐시스토어 업데이트를 반영할 수 있는가? 인데 제 지식으로는 내에서 생각해보면 안될 것 같아용 😞 페이지단에서 아폴로 캐시스토어에서 데이터를 가져오는 것이 아니라 서버사이드에서 주입한 데이터로만 렌더링을 하고있어서 이렇게 생각이 듭니당!
아폴로 캐시 스토어 하이드레이션을 위해서 `getServerSideProps`에 의존하는건 아닙니당! 그래서 getDataFromTree를 쓸 필요가 있을까? 생각이 들어용...
아아... 혜성님 말씀을 이해는 했는데... 오우...
getDataFromTree
를 사용해서 아폴로 캐시 스토어 데이터를 찾아서 컴포넌트의 주입해주는걸 말씀하시는거죠?? 그래서 HoC로 만들어서 하는거구요... 이해는 갔는데....
t
제가 최신버전의 Next.js를 실제 대 고객용으로 쓰고있진않아서 ㅠㅠ 뭔가 인사이트있는 답변을 드리기가 힘드네요 ㅋㅋ
h
많이 구리네요 ㅋㅋㅋㅋ 네비게이션할 때 preloading 때문에 렌더링까지 할 필요가 없긴 할건데
디스커션 참여한 사람들이 이렇다할 API 제안을 안하는게 놀랍긴한데...
저라면 이런식으로 디자인 할거 같아요
Copy code
const MyQuery = makeQuery(graphql`
  query MyQuery { ... }
`);

function MyComponent({ preloadedData }) {
  const { data } = MyQuery.use(...);
};

export default MyComponent;

export async function getServerSideProps() {
  const preloadedData = await MyQuery.preload(...);
  return {
    props: { preloadedData },
  };
};
저도 Next를 안쓰는지라 의존성 주입 어떻게 할지는 문서를 죄다 뜯어봐야 알듯
u
우선 혜성님과 지혁님의 답변으로부터 뭔가 영감을 받긴 해서 시도해보고 올게용 🙂 감사합니다!
👴 1
t
두분 모두 화이팅입니다 ㅎㅎ Apollo + Next.js 연동하는 방법, 사례로 담에 발표하시면 좋겠네용 ㅋㅋ
y
🙇 답변해주셔서 감사합니다