본문으로 바로가기

 

프론트 : Next + node(서사렌과 동적 라우팅을 위한 커스텀 프론트 서버. node면 됩니다만 express를 주로 사용합니다.)

백엔드 : 원하는 프레임워크 (저는 express를 썼습니다.)

 

프론트 서버는 서버 사이드 렌더링을 위해 존재하는 것이지 백엔드 서버에서 데이터를 받아오기 위해서 존재하는게 아닙니다. 

 

이런 방식으로 프로젝트를 구성하는 이유는 아래와 같다.

/post/:id와 같이 동적인 파라미터가 들어가게 되면 커스텀 서버 API가 필요하다. (https://nextjs.org/docs/advanced-features/custom-server)이는 Next에서는 서버렌더링을 하기 때문에 /post/13을 요청하면 page의 구조에 따라 /page/post/13.js를 렌더링하려고 하기 때문이다.

 

Data Fetching 플로우

 

중요한 건, Component에서 직접 데이터 페칭을 하는 것이 아니라 데이터 페칭을 redux에서 일괄적으로 관리한다는 것이 좋다는 것입니다. (그러나 모든 페칭을 Redux에서 관리할 필요는 없으니 강박적으로 할 필요는 없습니다)

 

이는 Container + Presenter Pattern 디자인 패턴에서 추구했던, 데이터 페칭과 state를 관리하는 컴포넌트와 이를 렌더하는 컴포넌트를 분리하려고 하는 목적입니다. 

 

또 다른 목적으로는 최적화를 위해 컴포넌트 분리에 있어 state관리가 힘들어지므로 부모-자식 관계와 상관없이 일괄적으로 state를 관리하려는 redux 본연의 목적입니다.

 

물론 컴포넌트단에서 api를 직접 요청하는 것도 틀린 방법은 아닙니다. 비동기 처리를 위해 redux를 사용하는 건 결국 좀 더 편리하자고 사용하는 것이기 때문입니다. 

 

 

코드를 곁들여 설명하자면 아래와 같이 직접 컴포넌트 단계에서 axios를 날리는 것이 아니라 (물론 이렇게 해도 됩니다.)

useEffect(() => {
  axios.post("/api/mostliked").then((res) => {
    setMostLiked(res.data.post);
  });
}, []);

아래 같이 dispatch를 날리는 방식으로 처리합니다. (useEffect에서 dispatch를 사용하는 예시를 코드에서 뒤져봤는데 못 찾았네요)

const onUnfollow = useCallback(userId => () => {
    dispatch({
      type: UNFOLLOW_USER_REQUEST,
      data: userId,
    });
}, []);

 

물론 직접 컴포넌트 단계에서 데이터 페칭을 진행한다고 해서 문제가 생기진 않습니다.

 

 

1️⃣ 프론트 단에서 특정 이벤트 트리거될 시 Redux Action을 날린다. useEffect를 통해서든, 특정 버튼을 누르는 이벤트 등 여러 동작이 될 수 있겠다.

 

2️⃣ Redux 단에서 saga나 thunk 등을 이용해 비동기적 액션을 날린다. axios를 통해 데이터를 페칭해오고페칭의 성공/실패 여부에 따라(async/await나 yield) 또 Redux Action을 처리한다. (Redux state에 따라 해당 state의 영향을 받는 컴포넌트들은 자동으로 리렌더링된다) 

 

3️⃣ 당연히 동적 라우팅을 통해 getInitialProps/getStaticPahts/getStaticProps/getServerSideProps 단계에서 dispatch를 날릴 수도 있습니다. Next의 이점을 최대한 살리려면 당연히 이러한 SSR, SSG 레벨의 데이터 페칭을 자주 사용해야 겠죠., 하여튼 무언가 정보를 필요로 하면 비동기적 redux로 처리합시다.

 


darren, dev blog
블로그 이미지 DarrenKwonDev 님의 블로그
VISITOR 오늘 / 전체