next.js
1. 리액트 컴포넌트 파일에서 module.css를 import 해서 사용하기
2. global.css 적용할 때는 _app컴포넌트에 적용하기
3. alias 라는 거로 @ 설정 -> @ 사용하면 프로젝트 최상위 폴더를 기준으로 경로를 사용할 수 있음.
-> 현재 파일의 경로랑 상관없이 사용 가능
4.파일시스템 기반 라우팅
-> 파일의 경로가 주소에 매칭되는 라우팅 방식 -> 폴더를 만들고 자바스크립트 파일을 만들면 됨
5. next.js의 폴더구조는 next.js에서 만든 거기 때문에 꼭 pages로 만들어야 하고 이 안에 파일을 넣으면 페이지가 됨
6. index.js는 최상위 페이지(홈페이지)
7.페이지에 사용되는 파일들은 꼭 export default로 해야한다.
8. pages폴더 안에 product 폴더를 만들고 자식 파일을 생성하면 경로는 product/1,2,3 ...이런식으로 생성
9. 파일 이름을 [id].js 로 설정하면 대괄호 안에 있는 값은 변수처럼 설정 가능,
-> next 에서는 param이라고 부름
10. 대괄호 표기법은 폴더에서도 자유롭게 사용 가능,
useRouter
import React from 'react'
import { useRouter } from 'next/router'
const product = () => {
const router = useRouter()
const { id } = router.query
return (
<div>1</div>
)
}
export default product
router 객체를 만든 다음에 react.query라는 객체에서 id값을 가져옵니다.
-> 여기서 id값은 파일 이름에 있는 그 id값이다. 파일이름이 [id.js]니까 const { id } = router.query로 작성
-> id값으로 param을 가져옴
import { useRouter } from 'next/router';
import { useState } from 'react';
import styles from './SearchForm.module.css';
export default function SearchForm({ initialValue = '' }) {
const router = useRouter();
const [value, setValue] = useState(initialValue);
const handleChange = (e) => {
setValue(e.target.value);
};
const handleSubmit = (e) => {
e.preventDefault();
if (!value) {
router.push('/');
return;
}
router.push(`/search?q=${value}`);
};
return (
<form className={styles.searchForm} onSubmit={handleSubmit}>
<input
className={styles.searchInput}
name="q"
value={value}
placeholder="찾고 싶은 옷을 검색해보세요."
onChange={handleChange}
/>
<button className={styles.searchButton}>검색</button>
</form>
);
}
router.push('/')를 통해 페이지 이동 가능
queryString
import React from "react";
import { useRouter } from "next/router";
const Search = () => {
const router = useRouter();
const { q } = router.query;
return (
<>
<div>Search 페이지</div>
<div>{q}검색결과</div>
</>
);
};
export default Search;
router.query객체에서 { q } 라는 이름으로 가져오고
jsx문법에서 { q } 를 화면에 보여준다.
하면 이렇게 쿼리스트링 변경에 따라 화면에 나옴
커스텀 app
페이지마다 공통으로 들어갈 레이아웃을 구현할 때 공통 컴포넌트를 _app컴포넌트에 넣어준다
import '@/styles/global.css';
export default function App({ Component, pageProps }) {
return <Component {...pageProps} />
}
app컴포넌트는 component 라는 prop를 받아서 렌더링, -> next.js페이지라고 보면
-> component 로 렌더링하고 pageProps로 내려주고 있음
import Container from "@/components/Container";
import Header from "@/components/Header";
import "@/styles/global.css";
export default function App({ Component, pageProps }) {
return (
<>
<Header />
<Container />
<Component {...pageProps} />
</>
);
}
공통으로 들어가는 <Header/>, <Container/> 컴포넌트를 넣어서 적용한다.
next.js 의 Document
import { Html, Head, Main, NextScript } from 'next/document'
export default function Document() {
return (
<Html lang="ko">
<Head />
<body>
<Main />
<NextScript />
</body>
</Html>
)
}
_Document.js라는 파일이 있음.
서버에서 렌더링 할 때만 이 컴포넌트를 실행하고 클라이언트 사이드에서는 실행하지 않는다.
react훅이나 인터렉티브한 자바스크립트 코드는 정상적으로 동작하지 않는다.
-> 주로 html 의 lang속성을 적용하고나 사이트 전체에 적용할 html 태그를 추가
next.js의 image컴포넌트
import React from "react";
import Image from "next/image";
const test = () => {
return (
<>
// 일반 img속성으로 이미지 불러오기
<img src="/images/product.png" alt="product" width={120} height={120} />
// next.js의 Image컴포넌트로 이미지 불러오기
<Image
img
src="/images/product.png"
alt="product"
width={120}
height={120}
/>
</>
);
};
export default test;
next.js의 Image 컴포넌트를 사용해서 이미지를 불러올 수 있다.
Image 컴포넌트를 통해 이미지를 불러오면 주소에 쿼리값이 들어가고 이미지 원본을 next.js서버를 한번 거쳐서 최적화된 크기의 이미지를 가져온다.
스크롤로 화면을 내릴 경우 일반 img로 불러온 이미지는 초기화면 부터 이미지가 있는반면에
Image 컴포넌트로 불러온 이미지는 이미지가 필요한 순간 직전에만 이미지를 불러온다
-> 레이지 로딩이라고 함 -> 페이지의 초기 로딩 속도가 훨씬 빨라진다.
-> 대신 이미지의 크기를 꼭 지정해줘야한다. ( 지정한 이미지 크기를 기준으로 최적화하기 때문)
import React from "react";
import Image from "next/image";
const test = () => {
return (
<>
<div style={{
position: "relative",
width: "50%",
height: "200px",
}}>
<Image fill
img src="/images/product.png"
alt="product"
style={{
objectFit: "cover",
}}/>
</div>
</>
);
};
이미지를 div태그로 감싸고 Image컴포넌트에 fill 속성을 사용하면 조상요소를 기준으로 이미지 크기를 유연하게 조절할 수 있다.
-> 이미지의 비율이 깨지지 않고 유지하면서 채우고 싶으면 Image 컴포넌트 안에 objectFit : "cover" 스타일 사용,
public 폴더에 있는 이미지가 아니라 외부에 있는 이미지를 불러와서 사용할 때는 이런 오류가 나서 next.config.js 파일에 따로 설정해줘야한다.
module.exports = {
images: {
remotePatterns: [
{
protocol: 'https',
hostname: 'example.com',
port: '',
pathname: '/account123/**',
},
],
},
}
이 코드를 넣어주면 된다.
Head컴포넌트
웹 브라우저의 탭 제목을 바꾸려면 Head 컴포넌트를 사용해서 타이틀을 넣어준다.
return (
<>
<Head>
<title>DdiShop</title>
</Head>
<SearchForm />
<ProductList className={styles.products} products={products} />
</>
);
}
모든 페이지 브라우저 타이틀 설정 가능!
import Container from "@/components/Container";
import Header from "@/components/Header";
import "@/styles/global.css";
import { ThemeProvider } from "@/lib/ThemeContext";
import Head from "next/head";
export default function App({ Component, pageProps }) {
return (
<>
<Head>
<title>DdiShop</title>
<link rel="icon" href="/images/emotion1.png" />
</Head>
<ThemeProvider>
<Header />
<Container />
<Component {...pageProps} />
</ThemeProvider>
</>
);
}
app 컴포넌트에 타이틀과 이미지를 설정하면 어떤 페이지든 브라우저 타이틀에 이미지 설정 가능!
ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ
내일 쓸거
'넥스트 제이에스' 카테고리의 다른 글
mongoDB였던것 (0) | 2024.02.26 |
---|---|
02.15 next.js의 프리렌더링 공부 (0) | 2024.02.15 |