Next.js에 대해서 정리해봄(2)

Designated Hitter Jack·2023년 11월 12일
0

SW 사관학교 정글

목록 보기
39/44
post-thumbnail

Next.js 에 style 적용하기

filename.module.css

CSS를 적용하고 싶은 파일 (NavBar.tsx) 의 이름에 맞게 NavBar.module.css 를 생성해준다.

@component/NavBar.module.css

.nav {
    display: flex;
    justify-content: space-between;
    background-color: tomato;
}

이렇게 CSS를 작성한 후 해당 파일에 import하기 위해선 다음과 같이 쓰면 된다.

@component/NavBar.tsx

"use client"
import Link from 'next/link'
import { usePathname } from 'next/navigation'
import styles from './navBar.module.css' //style을 import
export default function NavBar() {
    const pathname = usePathname();
    return <nav className={styles.nav}>
		//<nav className=nav> 로 쓰는 대신에 
		//<nav className={styles.nav}> 이런식으로 써야 한다. 
    <Link style = {{color: pathname === "/" ? "red" : "blue"}} className='Hello' href="/">
    Home
    </Link>
    <Link style = {{color: pathname === "/about"? "red": "blue"}} href="/about">
    About Us
    </Link>
    </nav>
}

CSS module

html 태그에 class를 추가할 때 JS property 형식으로 추가해야 한다.
이런식으로 작성한 class는 실제 브라우저에 읽는 html 태그에서는
class=”NavBar_nav__임의의 문자”와 같은 형식으로 만들어져 충돌을 피한다.

이런 식으로 클래스 이름이 랜덤으로 만들어지기 때문에 클래스명이 중복되어도 큰 문제가 발생하지 않는다.

"use client"
import Link from 'next/link'
import { usePathname } from 'next/navigation'
import styles from './navBar.module.css'
export default function NavBar() {
    const pathname = usePathname();
    return <nav>
    <Link className={pathname === "/" ? styles.active : ""} href="/">
    Home
    </Link>
    <Link className={pathname === "/about"? styles.active: ""} href="/about">
    About Us
    </Link>
    </nav>
}

서로 다른 className을 동일한 element에 적용하기

  1. 백틱(``)을 사용해 템플릿 리터럴로 각 className을 묶어서 표시하기
  2. 각 className을 원소로 갖는 배열로 묶은 후, 배열 끝에 [].join(” “)으로 한 칸 공백을 두고 합쳐버리기
"use client"
import Link from 'next/link'
import { usePathname } from 'next/navigation'
import styles from './navBar.module.css'
export default function NavBar() {
    const pathname = usePathname();
    return <nav>
    <Link className={`${styles.link} 
    ${pathname === "/" ? styles.active : ""}`} href="/">
    Home
    </Link>
    <Link className={[styles.link, 
        pathname === "/about"? styles.active: ""].join(" ")} 
        href="/about">
    About Us
    </Link>
    </nav>
}

styled JSX

return 으로 반환하는 html 태그에서 <style jsx>{`여기에 css 작성`}</style> 을 사용하여 CSS를 적용할 수 있다.

"use client"
import Link from 'next/link'
import { usePathname } from 'next/navigation'

export default function NavBar() {
    const pathname = usePathname();
    return <nav>
    <Link className={pathname === "/" ? "active" : ""} href="/">
    Home
    </Link>
    <Link className={pathname === "/about" ? "active" : ""} href="/about">
    About Us
    </Link>
    <style jsx global>{`
    nav {
        background: tomato;
    }
    a {
        text-decoration: none;
    }
    .active {
        color: white;
    }
    `}</style>
    </nav>
}

이렇게 jsx를 사용하면 class는 알 수 없는 16진수 숫자와 함께 랜덤생성 되며 이는 상위 페이지나 상위 컴포넌트에서 같은 class를 사용하더라도 충돌을 막아주는 역할을 한다.

그리고, Next.js 13에서 <Link> 안에 <a>를 사용할 수 없게 되어서 발생한 문제 같은데, jsx로 <Link>에 css를 적용하는 것이 불가능하다.

styled-jsx의 readme에서 보면, global 속성을 이용하여 <Link>는 브라우저가 읽을 때 <a>로 parsing되기 때문에 jsx를 global로 적용하고 a 태그에 CSS를 작성하는 것으로 어느 정도 비슷하게 할 수는 있지만 아직 className을 적용하는 것을 완벽하게 대체하지는 못하는 것 같다.

application에 global style 추가하기

font-size, font-family 등 사이트에 전역적으로 스타일을 적용하는 방법

app component

어떤 component에 대한 일종의 청사진.

인터넷에서 찾을 수 있는 여러 강의들에선 ./pages/_app.tsx 등의 파일을 만들고 그 파일 안에 모든 페이지에서 공용으로 사용하는 style이나 elements를 쓰라고 했었지만 Next.js 가 13으로 업데이트 되고 나선 이 역할을 기본으로 생성되는 파일 layout.tsx에서 하게 된다!

마찬가지로 공용으로 사용하는 style은 자동으로 생성되는 globals.css 안에 적어주면 자동으로 적용된다.

@app/layout.tsx

import type { Metadata } from 'next'
import { Inter } from 'next/font/google'
import NavBar from '../components/NavBar';
import './globals.css'

const inter = Inter({ subsets: ['latin'] })

export const metadata: Metadata = {
  title: 'Create Next App',
  description: 'Generated by create next app',
}

export default function RootLayout({
  children,
}: {
  children: React.ReactNode
}) {
  return (
    <html lang="en">
      <body className={inter.className}>
        <NavBar />
        {children}
      </body>
    </html>
  )
}

RootLayout()

이런 식으로 RootLayout 함수 안에 모든 페이지에서 공용으로 사용할 수 있도록 import 해온 <NavBar /> 태그를 가져와 모든 페이지에서 navigation 상단 바를 사용할 수 있게 했다. 이렇게 만든 후 각 페이지에 이미 작성했던 <NavBar /> 태그는 지워주면 이전과 다름없이 사용할 수 있다.

이 RootLayout함수는 Next.js에서 구현된 모든 컴포넌트를 불러오는 역할을 하므로 지우거나 함부로 수정해서는 안 된다.

metadata

SEO(search engine optimize)과정에서 사용할 수 있도록 검색 봇에게 title과 description을 제공하는 기능이다.

profile
Fear always springs from ignorance.

0개의 댓글