🐕 install
npx create-next-app@latest
# or
yarn create next-app
# or
pnpm create next-app
자바스크립트를 사용하고자하는 경우엔 다음과 같이 명령어를 입력한다.
project 이름을 입력하지 않는 이유는 입력하면 대충 앎
npx create-next-app@latest --typescript
# or
yarn create next-app --typescript
# or
pnpm create next-app --typescript
타입스크립트를 사용하고싶다면 --typescript를 붙여주면 된다.
👻라이브러리 설치
npm install react-icons --save
$ npm install next-themes
# or
$ yarn add next-themes
https://react-icons.github.io/react-icons/
https://www.npmjs.com/package/next-themes
react-icon과 next-themes을 설치해주겠습니다.
icon은 말그대로 icon 컴포넌트를 제공해줍니다. 사용법은 매우 간단합니다.
사용하고싶은 아이콘을 클릭하면 import할 이름이 복사됩니다.
각 경로에 맞춰 import해주면 끝입니다.
import { MdLightMode } from 'react-icons/md';
import { BsFillMoonFill } from 'react-icons/bs';
이런식으로 앞 2글자와 폴더경로가 일치하는것을 확인할 수 있습니다.
<MdLightMode
className="cursor-pointer text-xl hover:text-amber-500"
onClick={() => setTheme('light')}
/>
컴포넌트 형태로 사용할 수 있으며 class와 onClick이벤트 등
일반 html 태그처럼 사용할 수 있어요
🥶 next-themes
다크모드를 간단하게 구현할 수 있도록 도와주는 라이브러리입니다.
열심히 tailwind로만 구현했는데 더 편한게 있었네요 사용법은 다음과 같습니다.
src/app/Providers.jsx
'use client';
import { ThemeProvider } from 'next-themes';
export default function Providers({ children }) {
return (
<ThemeProvider enableSystem={true} attribute="class">
<div className=" min-h-screen select-none text-gray-700 transition-colors duration-300 dark:bg-gray-700 dark:text-gray-200">
{children}
</div>
</ThemeProvider>
);
}
'use client'를 통해 클라이언트에서 사용할 컴포넌트라는 것을 명시해줍니다.
enableSystem | 시스템의 다크모드 기본 설정을 활성화할지 여부를 결정하는 boolean 값입니다. 이 속성이 true이면 사용자의 다크 모드에 대한 기본 설정을 감지하여 테마를 제공합니다. |
attribute | 테마를 전환하는 데 사용할 속성을 지정합니다. |
전 attribute를 class로 지정하여 class 방식으로 테마를 전환하도록 했습니다.
tailwind css에서도 비슷한 설정을 했었던 기억이 나네요
tailwind.config.js도 수정해주겠습니다.
/** @type {import('tailwindcss').Config} */
module.exports = {
content: [
'./app/**/*.{js,ts,jsx,tsx,mdx}',
'./pages/**/*.{js,ts,jsx,tsx,mdx}',
'./components/**/*.{js,ts,jsx,tsx,mdx}',
// Or if using `src` directory:
'./src/**/*.{js,ts,jsx,tsx,mdx}',
],
theme: {
extend: {},
},
plugins: [],
darkMode: 'class',
};
이렇게 darkMode를 추가해주시면 됩니다. 여기서도 class로 추가해주겠습니다.
수동으로 다크모드를 전환할 수 있는 버튼을 만들기 위해서는
next-themes가 제공하는 useTheme 훅을 이용합니다.
import { useTheme } from 'next-themes';
const { systemTheme, theme, setTheme } = useTheme();
useTheme 훅은 객체를 반환합니다.
systemTheme | 사용자의 운영 체제가 어떤 테마로 설정되어있는 지 나타내는 boolean값입니다. 밝으면 false 어두우면 true입니다. |
theme | 현재 활성화된 테마를 나타내는 문자열입니다. 값은 light , dark 혹은 system등이 될 수 있습니다.. |
setTheme | 밝은 테마와 어두운 테마 사이를 전환하는 데 사용할 수 있는 함수입니다. 'light'를 인수로 사용하면 light모드로 'dark'를 인수로 사용하면 dark 모드로 전환합니다. |
위 세가지 변수들을 통하여 수동으로 전환할 수 있는 버튼을 만들 수 있어요
const [mounted, setMounted] = useState(false);
useEffect(() => setMounted(true), []);
컴포넌트가 처음 mount 되는 경우에만 setMounted 를 통해 state를 true로 바꿔줍니다.
의존성배열에 빈 배열을 주는 경우 처음 마운트 되었을때만 실행되기 때문에 가능한 방법입니다.
const currentTheme = theme === 'system' ? systemTheme : theme;
theme이 system인 경우엔 systemTheme을 따르게하고
아닌 경우엔 theme을 따르도록 합니다.
{mounted &&
(currentTheme === 'dark' ? (
<MdLightMode
className="cursor-pointer text-xl hover:text-amber-500"
onClick={() => setTheme('light')}
/>
) : (
<BsFillMoonFill
className="cursor-pointer text-xl hover:text-amber-500"
onClick={() => setTheme('dark')}
/>
))}
그 뒤 mounted가 true일때 삼항연산자를 통해 조건부 렌더를 시키면 끝입니다.
🌞Link
import Link from 'next/link';
import React from 'react';
export default function MenuItem({ title, address, Icon }) {
return (
<div>
<Link href={address} className="mx-4 hover:text-amber-600 lg:mx-6">
<Icon className="mx-4 text-2xl sm:hidden" />
<p className=" my-2 hidden text-sm sm:inline">{title}</p>
</Link>
</div>
);
}
next/link에서 import해옵니다.
역할은 react-router-dom이 제공하는 Link 컴포넌트랑 비슷한 것 같네요
사용법도 유사한데 href attribute를 통해 경로를 지정해줍니다.
위에 들어가는 href 경로는 next.js는 파일기반 라우팅을 지원하기때문에 파일에 맞춰서 작성해주면됩니다.
<MenuItem title="HOME" address="/" Icon={AiFillHome} />
<MenuItem title="ABOUT" address="/about" Icon={BsFillInfoCircleFill} />
이렇게 /about으로 path를 지정해두면 about 폴더에 있는 pages.jsx를 렌더하게됩니다.
<Link
className={`m-4 p-2 font-semibold hover:text-amber-600 ${
genre === param
? 'rounded-lg underline decoration-amber-500 decoration-4 underline-offset-8'
: 'text-gray-500'
}`}
href={`/?genre=${param}`}
>
이런 느낌으로 querystring 을 이용할수도 있습니다.
genre 쿼리의 밸류에따라 css 포커스를 다르게하며 링크도 쿼리를 통해 지정해줍니다.
import { useSearchParams } from 'next/navigation';
export default function NavbarItem({ title, param }) {
const searchParams = useSearchParams();
const genre = searchParams.get('genre');
이 역시 react-router-dom 의 SearchParams와 비슷한 역할을 합니다.
하지만 import 경로는 next/navigation이네요
사용법은 간단합니다.
useSearchParams훅의 호출 반환값을 담아두고
get메서드를 이용해 우리가 지정한 쿼리의 밸류를 받아옵니다.
SearchParams훅이 반환하는 객체는 다음과 같은 메서드를 지닙니다.
http://localhost:3000/?genre=fetchTrending
위와 같은 경로에 접속하는 경우
get을 이용해서 받아온다고 했을때 genre의 값은 fetchTrending이 됩니다.
😋metaData
이게 날 매우 화나게 했다.
13.1 이하 버전에서는 Head.js 컴포넌트내부에서 HTML의 head 태그안에 들어갈
메타데이터, title등을 작성했다고 하는데 내 환경에서는 Head.js가 동작하지않았으며
next.js는 마이그레이션을 말그대로 칼들고 협박하고있었다.
어쩔 수 없이 next.js가 요구하는 형식으로 metadata 작성방법을 바꾸었지만
제대로 이해하지 못해서 파비콘 설정을 어떻게 해야할지 아직도 감이 안잡힌다.
src/layout.jsx
export const metadata = {
title: 'IMDB',
robots: {
index: true,
},
description: '엄준식',
};
layout.jsx파일에서 metadata 변수를 작성한 뒤 내보내기해준다.
title에 들어갈 값이 웹페이지의 title이 된다.
🐶마치며
뭔가 획기적으로 편해지면서도
이전에 사용했던 라이브러리의 개념들과 비슷한 녀석들이 많이 나와서
무리없이 이해할 수 있어서 좋네요
'Next.js' 카테고리의 다른 글
next-auth를 이용해 Google 로그인 구현하기(기초) (1) | 2023.05.31 |
---|---|
Next.js에서 에러를 핸들링 하는 방법 (0) | 2023.05.27 |
Next.js에서 환경변수 .env를 클라이언트 사이드에서도 사용하려면..? (0) | 2023.05.05 |
SSR, CSR, SSG, ISR 이해해보기.. (4) | 2023.04.30 |
Link 컴포넌트는 어떻게 흰 화면을 보여주지 않을 수 있을까? (0) | 2023.04.28 |