Next - getServerSideProps 사용하여 데이터 먼저 받아오기

 

Next 동작방식

Next는 브라우저가 서버에 데이터가 없는 HTML화면과 JS파일을 요청하고 모두 로드가 되면 사용자의 상호작용에 따라 JavaScript를 통해 동적으로 렌더링한다. 그렇기 때문에 속도는 빠르지만 데이터가 나중에 넣어지기 때문에 데이터에 따라 페이지가 다르면 깜빡하는 현상이 발생하게 된다.

예를 들면 로그인했을 때는 내 정보를 보여주고 하지 않았을 때는 로그인하는 창이 뜬다고 하면 로그인하는 창이 잠깐 뜬 다음 내정보가 뜨게 된다. 이런 깜빡하는 현상이 거슬릴 수가 있는데 그걸 페이지 요청 시 서버사이드 렌더링을 통해 서버 측 데이터를 먼저 받아온 후 렌더링 시키는 방법이 있다.

getServerSideProps

SSR(서버사이드 렌더링)일때 활용하는 서버측에서 Props를 가져오는 메소드이다.

서버사이드렌더링 하고싶은 Page (pages/page.js)

import wrapper from '../../store/configureStore';
import axios from 'axios';
import { END } from 'redux-saga';

export const getServerSideProps = wrapper.getServerSideProps(async (context) => {
  // 프론트서버에서실행 (주체는 프론트서버에서 백엔드로 쿠키전달 x 그래서 아래 )
  const cookie = context.req ? context.req.headers.cookie : ''; // 쿠키까지 전달
  // if문이랑 쿠키초기화를(아래) 안쓰면 다른사람이 사이트 들어와도 로그인되어있음 (프론트서버에서 쿠키가 공유되는 현상)
  axios.defaults.headers.Cookie = '';
  // 서버일때 && 쿠키가 있을때만 쿠키 넣어주기 아니면 위에 줄 초기화
  if (context.req && cookie) {
    axios.defaults.headers.Cookie = cookie;
  }
  context.store.dispatch({
    type: LOAD_MY_INFO_REQUEST
  });
  context.store.dispatch({
    type: LOAD_POSTS_REQUEST
  });

  context.store.dispatch(END);
  await context.store.sagaTask.toPromise(); // 이건..사용방법 하라고
  // return { props: { data:123 }} // Home({ data })이렇게 전달가능
});

  • 위에 3줄은 로그인할 때 쿠키까지 전달하고 다른 사용자와 쿠키가 공유되는 현상을 막아주는 코드이다.
  • 먼저 서버사이드렌더링을 통해 받고 싶은 데이터를 context.store.dispatch({ 를 통해 선언해준다.
  • context.store.dispatch(END);는 dispatch를 통해 받아올 데이터를 성공될때까지 기다려준다.
  • 마지막 줄에 return { props: { data:123 }} 을 사용하게 되면 데이터를 컴포넌트의 Props로 전달할 수 있다.
    (위에 예시는 useSelector로 데이터를 가져와서 쓰지 않았다.)

getServerSideProps부분이 실행되면 index Reducer에 case HYDRATE: 부분이 실행된다.

rootReducer (/reducers/index.js)

const rootReducer = (state, action) => {
  switch (action.type) {
    case HYDRATE:
      console.log('HYDRATE', action);
      return action.payload;
    default: {
      const combineReducer = combineReducers({
        ...
      });
      return combineReducer(state, action);
    }
  }
};


그래서 redux devtools 페이지 요청할때 보면


__NEXT_REDUX_WRAPPER_HYDRATE__부분에 데이터가 채워지는 것을 볼 수 있다. @@INIT랑 DIFF로 비교해보세요!