Next.js

Next.js quick start 환경 설정 및 간단한 사용법

냠냠맨 2023. 5. 4. 16:01

🐕 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/

 

React Icons

React Icons Include popular icons in your React projects easily with react-icons, which utilizes ES6 imports that allows you to include only the icons that your project is using. Installation (for standard modern project) npm install react-icons --save Usa

react-icons.github.io

https://www.npmjs.com/package/next-themes

 

next-themes

An abstraction for themes in your Next.js app.. Latest version: 0.2.1, last published: 7 months ago. Start using next-themes in your project by running `npm i next-themes`. There are 143 other projects in the npm registry using next-themes.

www.npmjs.com

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이 된다.


🐶마치며

뭔가 획기적으로 편해지면서도

이전에 사용했던 라이브러리의 개념들과 비슷한 녀석들이 많이 나와서

무리없이 이해할 수 있어서 좋네요


이해했다고 생각할 때가 가장 무서울 때다.

 

반응형