지금까지 상황)
지도 api를 가지고와서 매장의 위치가 핀에 꽂혀있을 수 있도록 만들고 해당 핀을 누르면 그 매장의 상세정보를 보려고 한다.
그럼 그 핀에 알맞는 상세page가 필요하게 되었다.
과정)
[name].tsx 파일을 pages 하위 파일로 만들어 준다. 여기서 []안에 들어가는 params를 지정해주면 페이지가 생성된다.
유동적으로 페이지를 만들 수 있다는 것.
예시 코드)
//[name].tsx
const StoreDetail : NextPage<Props> = ({store:Store})=>{
return <div>detail<div>;
}
export default StoreDetail
export const getStaticPaths: GetStaticPaths = async()=>{
const paths = [{params : {name: 'test'} }];
return {paths,fallback:false} //paths를 반환
}
//위와 같은 코드로 작성시 [name].tsx라고 지정해준게 test.tsx라고 하나의 페이지가 만들어진다.
그럼 이 함수는 어디다가 쓰면 될까?
많은 페이지가 필요할때 그때 마다 하나씩 만들지 않고 값만 넘겨주면 알아서 생성되도록 해주면 효율성이 좋겠다.
또, getStaticPaths는 getStaticProps와 같이 쓰여야한다.
export const getStaticProps: GetStaticProps = async({params})=>{
return {props:{}}
}
여기까지 만들고나서 실행 해보면 /test라는 경로에 detail이라는 글자를 확인할 수 있다.✅
그러나, /test2와 같이 경로를 입력하면 페이지가 뜨지 않는다. 즉, paths 변수에 지정해놓은 페이지들만 생성되다는것을 확인
그럼 저 paths에 매장들의 이름을 넣어주면 되겠다.
export const getStaticPaths: GetStaticPaths = async()=>{
const stores = (await import('../public/stores.json')).default
const paths = stores.map(store=>({params : {name: store.name} }));//모든 스토어의 경로를 만들어줌
return {paths,fallback:false}
}
//여기있는 Params에 값이 들어가서 return이 가능하다.
export const getStaticProps: GetStaticProps = async({params})=>{
const stores = (await import('../public/stores.json')).default
const paths = stores.map(store=>store.name ===params.name)
return {props:{store}}
}
paths는 가지고 있는 매장들(stores)을 map돌려 params를 매장들의 이름으로 넘긴다.
그럼 아마도 /빽다방 <= 이런 경로가 되겠지ㅎ
그리고 아까 말한 getStaticProps를 사용해서 해당 페이지의 props로 넘겨준다.
{params}에 위의 코드에서 가져온 store.name들이 들어간다음에 가지고 있는 데이터와 일치한 매장들의 이름을 props로 넘겨준다.
잘 넘어왔는지 확인해보자면 요롷게 확인할 수 있지않을까?
const StoreDetail : NextPage<Props> = ({store:Store})=>{
return <div>name:{store.name}<div>; //빽다방
}
좀 더 추가적인 정보라면,
getStaticPaths는 페이지의 경로를 정적으로 생성한다. 즉, build타임에 stores~이 구문을 실행하여 API 또는 JSON 으로 저장된 데이터를 확인한 뒤, 미리 페이지를 프리렌더링 해놓는다👍
위의 코드를 보면 fallback이라는 속성을 볼 수 있다. 공식문서를 참고하면 가장 잘 나와있다. true/false/blocking으로 값을 줄 수 있다.
false : 빌드타임에 미리 경로를 다 생성해둔다, 만약 찾을 수 없는 경로를 입력한다면 바로 404페이지를 띄운다.
true : 똑같이 빌드타임에 경로를 생성해두지만, 존재하지 않더라도 약간의 로딩 후 404페이지를 띄우거나 안보이게 할 수 있다.
//true code
export const getStaticProps: GetStaticProps = async({params})=>{
const stores = (await import('../public/stores.json')).default
const paths = stores.map(store=>store.name ===params.name) //해당하는 매장을 못찾겟지?
if(!store){
return {
notFound : true, //404페이지로 보낸다.
};
}
return {props:{store}}
}
위 처럼 만약 store이 없다면? notFound를 줘서 404페이지로 보낸다.
그리고 이 404페이지를 띄우기 까지의 과정 또한
const StoreDetail : NextPage<Props> = ({store:Store})=>{
const router = useRouter();
if(router.isFallback){
return <div>Loading...<div>
};
}
위와 같이 isFallBack을 사용해서 사용자에게 페이지를 찾는 중이다~ 하고 Loading을 띄워줄 수 있다.
이렇게 아주 잠깐이지만 Loading이라는 글자를 확인 할 수 있고 404를 띄운다.
다시 과정을 정리하자면, store가 없어도 getStaticProps까지 함수가 실행될것이고 거기서 store을 못 찾으면 return 으로 404가 뜬다.
이 과정중에 설정해놓은 isFallBack속성으로 Loading이라는 구문을 추가할 수 있다.(store가 있다면 당연히 원래대로 진행되듯이 name이 뜰것이다.)
❓그럼 언제 true설정은 언제 하는게 좋을까?
수만개의 매장들이 있다면 build타임에 모든 경로를 만들어내기가 비효율적일것이다. 그러니 미리 최소한의 경로만 가지고 있고 유저가 때에 따라서 요청할때 그제서야 경로를 만드는 것이 좀 더 효율적일 수 도 있다.
❓DB에 새로 추가되는 게시물이나 매장이 있을 경우에 사용할 수 있다.
빌드타임에 미리 새로 추가가 될 것을 모르니 프리렌더링을 할 수 없기 때문이다.
❗️누군가가 최초로 호출을 하면 새롭게 만들어진 HTML파일을 정적페이지로 만들어서 가지고 있어 다음 사람이 호출하면 getStaticProps로 안가고 pre-rending된 페이지를 볼 수 있다.(매번 getStaticProps가 실행되는 것이 아니라는 점)
Blocking
true와 비슷하지만 약간의 시간을 가지고 404페이지를 던진다. 등록되지 않은 페이지에 접근을 하면 fallback이란느 Loading문구는 뜨지 않는다.
과정) getStaticPath > getStaticProps > 없넴 그럼 404(아까 위의 조건식으로 if(!store) 구문이 실행된다. 대신, isFallback은 안된다.
최초 HTML 생성과정 후 정적페이지로 되는 과정은 true와 동일하다.
404페이지 만들기
pages폴더 하위에 404.tsx 만들어서 꾸며주면된다. 간단 😎
'next.js' 카테고리의 다른 글
서버로 데이터 전송 (0) | 2023.05.04 |
---|---|
next.js server (0) | 2023.05.01 |
[next.js] Image (0) | 2023.04.05 |
[Next.js] link (0) | 2023.04.04 |
Next.js <getStaticProps> (0) | 2023.04.04 |