[생활코딩] Next.js 13 요점 정리 - 2

혜혜·2023년 9월 27일
0

Next.js

목록 보기
2/4
post-thumbnail

💡 10. 글목록 가져오기

  • 만약 Server Component의 경우, onClick, onChange와 같은 API들을 사용하면 오류 발생!
  • Next.js에서는 특별한 조치를 하지 않는 한, Server Component로 간주

  • 사용자와 상호작용 하지 않는 부분Server Component로 개발하는 게 유리함!

  • 예를 들어, 위 그림처럼 Button만 사용자와 상호작용 할 필요가 있으면, 해당 부분만 따로 Client Component로 만드는 게 유리

  • 사용자와 상호작용Client Component

  • 정보를 단순히 디스플레이Server Component

  • 강의에서는 먼저 Client Component로 개발하여 비효율을 확인하고, Server Component로 전환하는 식으로 진행

  const [topics, setTopics] = useState([]);
  useEffect(() => {
    fetch('http://localhost:9999/topics')
      .then(resp=>resp.json())
      .then(result => {
        setTopics(result);
      });
  }, []);

이렇게 코드를 짜면,

  • Client Component에서만 사용할 수 있다는 오류가 발생함
  • 또한 이 모듈을 사용하려면, 맨 위에 "use client"를 적으라는 메시지가 적혀 있음
  • "use client"를 추가하고 실행시켜도 오류가 발생하는데,
    그 이유는 "use client" 디렉티브로 인해 해당 컴포넌트는 Client Component가 되었는데, metadataServer Component에서만 사용되는 거라 나타나는 오류로, metadata 부분을 주석 처리 해주면 해결된다.

📍Client Component를 사용할 때의 단점

  1. JavaScript를 off 시키면, 서버와 통신하는 동적인 데이터가 보이지 않음
  2. 만약 DB와 id, password 등을 주고 받아야 하는 경우라면, 노출 가능성

=> Server Component로 바꿔 보자

  • "use client" 디렉티브 제거
  • useState, useEffect hook 제거하고 비동기 호출
  • 이렇게 하면 "서버" 쪽에서 fetch() 메소드가 호출되고, 그 다음 json()을 실행시켜 topics 데이터를 가져옴
  • 이 동적인 데이터를 저장해 놓고, 최종적인 정적인 내용만 클라이언트로 가져온다!
  • metadata도 다시 사용 가능

✔️ 클라이언트로 JavaScript를 전송하지 않으니까 용량이 절약됨
✔️ fetch()로 호출하는 서버와 현재 파일이 동작하는 서버가 같은 서버거나 가까이 있는 서버라면, 굉장히 속도가 빠름
✔️ 서버 쪽에서 렌더링을 끝내고 보내기 때문에, 리로드를 시켜도 똑같이 동작함

+) 서버와 클라이언트를 동시에 켜는 방법은, 터미널을 2개 열어서 실행

💡 11. 글 읽기

  • '글 읽기'는 사용자와의 상호작용이 필요하지 않으므로 Server Component로 만들자
export default async function Read(props) {
  const resp = await fetch(`http://localhost:9999/topics/${props.params.id}`);
  const topic = await resp.json();
  return(
    <>
      <h2>{topic.title}</h2>
      {topic.body}
    </>
  )
}

💡 12. 글 생성

+) 나는 오류가 생기지 않았지만, 영상에서 오류가 나타난다면 단순히 .next 폴더를 지웠다가 다시 실행시켜 보는 게 일차적인 방법이 될 수 있다고 함!

  • onSubmit 이벤트는 사용자와 "상호작용"하는 부분이기 때문에, Client Component로 구현할 필요가 있음
    ⭐ 어떤 걸 Client Component로 하고 어떤 걸 Server Component로 할지 구분하는 게 중요할 듯.
"use client"

import { useRouter } from "next/navigation";

export default function Create() {
  const router = useRouter();
  return (
    <form onSubmit={(e) => {
      e.preventDefault();
      const title = e.target.title.value;
      const body = e.target.body.value;
      const options = {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json'
        },
        body: JSON.stringify({title, body})
      }
      fetch(`http://localhost:9999/topics`, options)
        .then(res => res.json())
        .then(result => {
          console.log(result);
          const lastid = result.id;
          router.push(`/read/${lastid}`);
        })
    }}>
      <p>
        <input type="text" name="title" placeholder="title" />
      </p>
      <p>
        <textarea name="body" placeholder="body"></textarea>
      </p>
      <p>
        <input type="submit" value="create" />
      </p>
    </form>
  )
}
  • Next.js 13에서 사용하는 건 app router이기 때문에, useRouter()next/router가 아닌 next/navigation에서 import 해야 한다는 점에 유의하자!

💡 13. cache

  • Next.js는 기본적으로 우리가 한 번 가져온 데이터를 "저장해 둔다"
  • .next 디렉토리 안에 저장된 정보가 보관됨
rm -rf .next
  • .next 폴더를 지우는 명령어 실행

  • 그런 다음 다시 npm run dev를 실행시키면 위와 같은 과정이 실행됨
  • cache "MISS"라는 건 일반적으로 생각하는 HIT, MISS에서의 MISS
  • 아직 한 번도 데이터를 액세스한 적이 없거나 데이터가 유효하지 않아서 다시 가져왔다는 의미

  • 여기서 리로드를 해 보면, cache "HIT"가 뜬다!
  • cache를 이용했다는 의미

✔️ 데이터를 가져온 후에 그것을 cache로 만들지 않으면, 성능은 다소 희생되겠지만, 강의에서는 단순한 진행을 위해 그렇게 진행함👀

  • cache에 대한 자세한 설명은 Next.js 공식 문서를 통해 확인 가능

cache를 사용하지 않는 방법

  1. revalidate : cache가 유지되는 시간 지정(ex. 10으로 지정하면 10초가 지나면 cache는 유지되지 않고 다시 만들어진다는 의미)

→ 이걸 '0'으로 지정하면, cache를 사용하지 않겠다는 의미와 동일

  1. no-store : cache 옵션을 no-store로 지정해주면 cache를 사용하지 않는다는 의미

⭐ cache를 잘 활용하면 성능을 아주 좋게 만들 수 있기 때문에, 추후에 꼭 공부하는 것을 권장👀

💡 14. update & delete 버튼 구현

  • useParams()를 사용하기 위해서, layout.js 전체를 Client Component로 바꿀 수도 있겠지만, 이렇게 하면 Server Component의 장점을 잃어버림

(기본적으로 Server Component가 가능하다면 Server Component로 사용하려고 노력하는 것이 좋다)

Client Component로 사용하고 싶은 부분만 Client Component화 해서 사용하자!!

→ 이 스킬이 되게 중요할듯...

"use client"
import Link from "next/link";
import { useParams } from "next/navigation";

export function Control() {
  const params = useParams();
  const id = params.id;

  return (
    <ul>
      <li><Link href='/create'>Create</Link></li>
      {id ? <>
        <li><Link href={"/update/"+id}>Update</Link></li>
        <li><input type="button" value="delete" /></li>
      </> : null}
    </ul>
  );
}
  • 이런 식으로 Client Component로 동작할 필요가 있는 부분만 분리하여 사용하자!

💡 15. 글 수정

  • UpdateCreateRead가 가능한 느낌
  • POST가 아닌 PATCH 메소드 사용!

💡 16. 글 삭제

  • DELETE 메소드 사용

💡 17. 환경변수와 졸업

  • dotenv를 설치하지 않아도 환경변수 사용이 가능한듯?
  • .env.local 파일 생성
  • 사용 방법은 비슷 (process.env.)

⭐ 환경변수에 저장될 수 있는 기밀 정보들은, 클라이언트 사이드에 노출되지 않는 것이 좋기 때문에 Server Component에서만 접속 가능!

  • 여기서 웹 브라우저를 위한 환경변수를 쓰고 싶다면, NEXT_PUBLIC_ 접두사로 붙이자!
profile
쉽게만살아가면재미없어빙고

0개의 댓글