아직 클론 코딩 단계~
#CSS
- inherit은 부모의 값을 따라간다.
position fixed인 child의 width를 부모와 같게 하려고 100%를 하는 경우가 있는데 잘 안먹힐 때가 있다.
그럴 때 inherit 속성을 사용하면 부모의 width와 동일하게 맞출 수 있다.
.child {
position: fixed;
width: inherit;
}
- css 변수 사용
css 파일에서 반복되는 값을 변수에 담아 사용할 수 있다.
// 정의
:root {
--background: #ffffff;
--foreground: #171717;
}
// 사용
body {
color: var(--foreground);
background: var(--background);
}
- svg 태그 색상 변경
svg 태그의 색상을 바꾸고 싶으면 fill을 사용한다.
.uploadButton svg {
fill: rgb(29, 155, 240);
}
- 다크모드 설정
css에서는 다크모드 설정도 지원한다.
다크모드일 때의 스타일이나 css 변수를 다르게 설정할 수 있다.
@media (prefers-color-scheme: dark) {
:root {
--background: #0a0a0a;
--foreground: #ededed;
}
}
- 반응형
화면 크기의 break point를 설정하여 반응형 디자인을 구현할 수 있다.
@media all and (min-width: 1300px) { // 1300px 부터 적용
.leftSection {
width: 275px;
}
.leftSectionFixed {
align-items: flex-start;
}
}
#Next
- next/image
// 사용
<Image src={imageSrc} alt="image" width={40} height={40} />
- next/link
페이지 내비게이션할 때 사용
import Link from next/link;
<Link href="/go/to/path">페이지 이동하기</Link>
- 현재 위치(Location)를 알아내는 방법들 (useSelectedLayoutSegment(), usePathname())
우선 위의 Hook을 사용하기 위해서는 클라이언트 컴포넌트로 변경해야 한다.
Tip.
- use로 시작하는 hook을 사용하면 클라이언트 컴포넌트로 바꿔야한다고 생각하는게 편하다.
- use~ Hook을 사용하기 위해 전체 서버 컴포넌트를 굳이 클라이언트 컴포넌트로 바꾸지 말고, 사용할 부분만 파일로 쪼개서 클라이언트 컴포넌트로 만들자.
(1) useSelectedLayoutSegment()
import { useSelectedLayoutSegment } from "next/navigation";
const segement = useSelectedLayoutSegment();
현재 위치가 localhost:3000/messages 라고 할 때
ㄴ segment는 messages다.
현재 위치가 localhost:3000/compose/tweet 이라고 할 때
ㄴ segment는 compose다.
ㄴ segments는 ['compose', 'tweet']다.
따라서 모든 sub path를 알고 싶다면 >>> useSelectedLayoutSegments
가장 상위 path만 알고 싶다면 >>> useSelectedLayoutSegment
하지만 segment값은 현재 위치해있는 Layout과도 연관되어 있기 때문에 공식문서를 잘 읽어보자!
https://nextjs.org/docs/app/api-reference/functions/use-selected-layout-segment
Functions: useSelectedLayoutSegment | Next.js
API Reference for the useSelectedLayoutSegment hook.
nextjs.org
(2) usePathname()
또 다른 방법으로는 usePathname이 있다.
import { usePathname } from "next/navigation";
const pathname = usePathname();
이건 쿼리스트링 이전까지 다 가져온다.
- useSearchParams로 쿼리스트링 값 가져오기
localhost:3000/search?q=123에서 123을 가져오고 싶을 때
import { useSearchParams } from "next/navigation";
const searchParams = useSearchParams();
const qString = searchParams.get("q");
const allQueryString = searchParams.toString(); // 이건 기존 search params 모두 가져오겠다. 라는 의미
- URL params 가져오기 (Path params)
폴더 구조가 [username]/status/[id]/photo/[photoId] 로 되어있을 때
username, id, photoId에 해당하는 값을 받아오고 싶다면
type Props = {
params: { username: string; id: string; photoId: string };
};
export default function PhotoId({ params }: Props) {
return <Home />;
}
#ContextAPI 사용하여 컴포넌트 간에 상태(state) 공유하기
"최신" 글 목록을 담고 있는 Tab1과 "인기" 글 목록을 담고 있는 Tab2가 있는 TabLayout이 있다고 가정해보자.
현재 선택된 Tab에 따라 Post(글) 목록이 바뀌어야 한다.
---> 이 때 TabLayout과 Post(글) 목록은 서로 state를 공유해야한다.
이런 상황에 ContextAPI를 사용하여 간단하게 구현할 수 있다.
(1) ContextProvider 만들기
"use client"; // useState()를 사용해야하므로 클라이언트 컴포넌트로 설정
import { createContext, ReactNode, useState } from "react";
export const TabContext = createContext({
tab: "최신",
setTab: (value: "최신" | "인기") => {},
});
type Props = { children: ReactNode };
export default function TabProvider({ children }: Props) {
const [tab, setTab] = useState("최신");
return (
<TabContext.Provider value={{ tab, setTab }}>
{children}
</TabContext.Provider>
);
}
(2) Provider 적용
state를 공유해야하는 컴포넌트들을 감싸면 된다.
export default function HomePage() {
return (
<div className={style.main}>
<TabProvider>
<Tab />
<PostList />
</TabProvider>
</div>
);
}
강의 예제에선 안나왔지만
useContext(TabContext); 하면 Tab 컴포넌트와 PostList 컴포넌트에서 state를 사용할 수 있다.
#외부 라이브러리
- dayjs로 날짜 포맷팅하기
예전에 moment.js를 많이 사용했는데 최근 급상승하게 된 dayjs 날짜 포맷 라이브러리
회사에서 프로젝트할 때 자주 사용했었다.
사용하기 아주 간편함!
(1) dayjs를 사용하면, 특정 Date가 현재(now)로부터 몇 시간전인지, 몇 분전인지를 쉽게 표시할 수 있다.
import dayjs from "dayjs";
import relativeTime from "dayjs/plugin/relativeTime";
dayjs.extend(relativeTime); // 플러그인과 함께 사용해야 함.
dayjs(target.createdAt).fromNow(true); // true를 넘기면 suffix(몇 분전에서 "전")를 없애는 역할
(2) 원하는 포맷으로 표시하기
dayjs(m.createdAt).format("YYYY년 MM월 DD일 A HH시 mm분");
- classnames 사용하여 조건부 class 설정하기 (with CSS Modules)
import cx from "classnames";
// 사용
<div className={cx(style.repostButton, reposted && style.reposted)}>
다양한 조합법이 있으니 공식 문서를 확인해서 필요한 걸 찾아 사용하도록 하자
https://github.com/JedWatson/classnames
GitHub - JedWatson/classnames: A simple javascript utility for conditionally joining classNames together
A simple javascript utility for conditionally joining classNames together - JedWatson/classnames
github.com
- faker를 사용하여 더미데이터 만들기
https://www.npmjs.com/package/@faker-js/faker
@faker-js/faker
Generate massive amounts of fake contextual data. Latest version: 9.2.0, last published: 7 days ago. Start using @faker-js/faker in your project by running `npm i @faker-js/faker`. There are 1442 other projects in the npm registry using @faker-js/faker.
www.npmjs.com
import { faker } from "@faker-js/faker";
const imageUrl = faker.image.urlLoremFlickr(); // 이미지
const text = faker.lorem.text(); // 텍스트
const avatarUrl = faker.image.avatar(); // 아바타 이미지
섹션 3 완료
'개발 > Next.js' 카테고리의 다른 글
[Next 14] 섹션 6 (마지막) (1) | 2024.12.23 |
---|---|
[Next 14] 섹션 5 (1) | 2024.12.09 |
[Next 14] 4. MSW, React-Query, react-intersection-observer (2) | 2024.11.25 |
[Next 14] 2. 라우팅, 레이아웃, 페이지, CSS Module (5) | 2024.10.28 |
[Next 14] 1. 인트로 (0) | 2024.10.21 |