getServerSideProps 는 페이지 렌더링 이전에 데이터를 먼저 fetch 해야할 때 사용한다. 즉, 컴포넌트 UI가 화면에 보여지기 이전에 getServerSideProps 에서 return 한 데이터를 pre-render 하여 컴포넌트 내에서 props로 전달받을 수 있다.
현업에서 서버쪽 요구사항을 구현하려면 getServerSideProps가 알맞은 선택지였고, 요구사항과 사용한 이유를 간략하게 설명해보겠다.
먼저, 요구사항은 다음과 같았다.
1. 첫번째 페이지 api call의 명세 : requestBody 에 {id : null, date : ''} 담아서 전송
2. 두번째 ~마지막 페이지 api call 명세 : 첫번째 페이지의 마지막 데이터 중 id와 date 를 requestBody 에 {id : 2234, date : '2023-03-11'}의 형태로 전송
api를 call 하는 onGridReady() 함수는 agGrid Library 내부에서 실행 및 감지되는 인터페이스로 ProductPage 컴포넌트가 mount 되는 시점 즉, useEffect hook에서 트리거된다. 따라서, onGridReady 내부에서 데이터를 선언하면 onGridReady가 호출될 때마다 데이터가 initialize되는 이슈가 있었다. 따라서, 전역변수로 관리되어야 했고 그 시점은 화면이 브라우저에 렌더링 되기 이전이 적합했기 때문에 next.js에서 제공해주는 getServerSideProps() 를 선택했다.
그렇다면, getServerSideProps 는 언제 실행되고 어떻게 해서 컴포넌트까지 데이터를 연결시킬 수 있는 것일까? 먼저 아래 코드를 살펴보자. (두개의 함수는 동일한 페이지에 세팅)
// declare getServerSideProps
export async function getServerSideProps() {
return {
props: { id: null, date: '' }, // will be passed to the page component as props as being {}
};
}
export default function ProductPage({ id, date }) {
const onGridReady = async (gridOption) => {
gridOption?.api?.setDatasource({
async getRows(params) {
try {
const blockSize = 50;
const filteredData = params.filterModel;
const rs = await ProductApi({
page: parseInt(params.startRow / blockSize) + 1,
size: blockSize,
search: {
id,
date,
...filteredData,
},
});
let lastRow = -1;
lastRow = rs.data.payload.content === rs.data.payload.content > 0;
const hasRow = rs.data.payload.content.length > 0;
if (hasRow) {
const index = rs?.data?.payload.content.length - 1;
// overide last value from server to current constant
id = rs?.data?.content[index].id;
date = rs?.data?.content[index].date;
params.successCallback(rs?.data?.content, lastRow);
} else gridOption?.api?.showNoRowsOverlay();
} catch (e) {
console.error(e);
params.failCallback([], 0);
}
},
});
gridOption?.api?.sizeColumnsToFit();
};
};
}