아직 클론 코딩 단계~

 

 

 

#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 완료

+ Recent posts