Vercel에서 만든 React 프레임워크
cd Documents
npx create-next-app@latest
,npx create-next-app@latest --typescript
code 프로젝트명
npm run dev
pages/ // HTML, App Container, 각종 페이지 등을 작성
_document.js // HTML
_app.js // Application Container. 공통의 레이아웃 작성
_error.js // Error Page
index.js // /로 시작되는 경로
static/ // 정적 파일 (이미지, 파일 등) 업로드
next.config.js // 환경 설정 파일. 라우팅 설정, ts, less 등 webpack 플러그인 설정.
function MyApp({ Component, pageProps }) {
return <Component {...pageProps} />;
}
export default MyApp;
_app.js
파일에서만 전역 CSS 적용가능 _app.js
필수, 컴포넌트명은 아무거나 가능_app.js
파일에선 전역 import할 것이 많아서 (google analytics, 검색엔진, 스크립트분석 등) 해당파일이 커지는건 원하지 않으므로, Layout.js
에서 코드를 작성한다.//Layout.js
import NavBar from "./NavBar";
export default function Layout({ children }) {
return (
<>
<NavBar />
<div>{children}</div>
</>
);
}
//_app.js
import Layout from "../components/Layout";
import "../styles/globals.css"; //이파일에서만 전역css import가능
export default function AnyApp({ Component, pageProps }) {
return (
<Layout>
<Component {...pageProps} />
</Layout>
);
}
getInitialProps
, getStaticProps
, getServerSideProps
중<meta>, <title>, <link>
정의가능<Html> <Head> <Main> <NextScript>
next/document
고 모든페이지의 Head속성을 조작할 때 사용한다.next/head
의 Head다.getStaticProps
나 getServerSideProps
를 적용할 수 없다.import Document, { Html, Head, Main, NextScript } from 'next/document'
class MyDocument extends Document {
static async getInitialProps(ctx) {
const initialProps = await Document.getInitialProps(ctx)
return { ...initialProps }
}
render() {
return (
<Html>
<Head />
<body>
<Main />
<NextScript />
</body>
</Html>
)
}
}
export default MyDocument
<Image>
- next/image<사용이유>
App에 image 삽입하면 해상도, 용량을 그대로 사용하여 리소스 낭비가 된다.
그래서 크기에 따라 리소스 최적화를 위해 NextJS<Image>
컴포넌트로 이미지 최적화 기능을 사용한다.
이미지의 여러 버전을 불러오고 OS, 기기 크기에 따라 이미지 최적화해준다. 그리고 캐싱으로 저장되며 다른 OS, 기기에서 사용가능하다.
<img>
태그 대신 next/<Image>
사용하기import Image from "next/image";
...
<Image src="me.png" alt="Picture of the author" width={500} height={500} />;
// index.js ex
export async function getServerSideProps() {
const { results } = await (
await fetch(`http://localhost:3000/api/movies`)
).json();
return {
props: {
results, // props에 원하는 데이터 api 넣기
},
};
}
//_app.js ex
export default function AnyApp({ Component, pageProps }) {
return (
<Layout>
<Component {...pageProps} />
</Layout>
);
}
// <props전달 순서>
// (index.js)getServerSideProps의 props가
// _app.js의 Component {pageProps}로 오고
// (index.js) Home의 props로 온다
// <Home {results} /> 예를들면 이렇게 들어오는 것.
pages/movies폴더 생성/all.js 생성
ex) http~/movies/all
pages/movies폴더 생성/index.js 생성
ex) /movies
ex) /movies/1212121
// pages/[변수명].js
import { useRouter } from "next/router";
export default () => {
const router = useRouter();
return (
<>
<h1>post</h1>
<p>postid: {router.query.변수명}</p>
</>
);
};
localhost:3000/3525332 접속하면 postid가 3525332으로 출력된다
pages/[변수명].js
값은 router.query.변수명
와 동일하다
[...params].js
[params].js
수정 - getServerSideProps
추가//[...params].js
// 컴포넌트 내부 router = 클라이언트에서 실행
export default function Detail({ params }) {
//{ params }추가
const router = useRouter();
const [title, id] = params || []; //params로 변경
return (
<div>
<h4>{title}</h4>
</div>
);
}
// getServerSideProps = 서버에서 데이터가져옴, 소스코드에 데이터담음
export function getServerSideProps({ params: { params } }) {
// console.log(ctx); //getServerSideProps(ctx)지원함
return {
props: {
params,
},
};
}
- || [] 추가 이유
미리렌더링으로 초기html 다운받아오고
아직 js다운안되서 useRouter가 정보를 못가져와서 에러난다.
그래서 초기에 빈배열 추가해줘서 오류 안나게 하고
js가 다시 렌더링하면 그때 빈배열아닌 router.query.params 출력한다