본문 바로가기



NextJs 09: Next.js 글입력 작성과 캐시처리



안녕하세요. 각성한 데브키라입니다. JSON Server를 사용하여 Next.js에서 글 입력 기능을 구현하는 방법에 대해 설명하겠습니다. JSON Server는 REST API를 모의로 구현할 수 있는 간단한 방법을 제공합니다. 이를 통해 개발 중인 프런트엔드 애플리케이션에 백엔드가 없어도 데이터를 생성, 읽기, 업데이트, 삭제(CRUD)할 수 있습니다.

 

fetch 함수에서 사용할 수 있는 캐시 옵션들은 다음과 같습니다. 이 옵션들은 요청 시의 캐싱 동작을 제어하는 데 사용됩니다. 이 포스팅에서는 no-store옵션을 사용하였습니다.

 

1. default: 브라우저의 기본 캐시 정책을 따릅니다. 명시적으로 캐싱 동작을 설정하지 않을 때 사용되는 기본값입니다.

2. no-store: 어떠한 캐시도 사용하지 않습니다. 매 요청마다 서버로부터 정보를 새로 받아와야 합니다.

3. reload: 캐시를 무시하고 서버로부터 새로운 정보를 가져옵니다. 하지만 새로 가져온 정보는 캐시에 저장될 수 있습니다.

4. no-cache: 캐시 된 복사본이 있더라도, 항상 서버에 검증을 요청합니다. 서버는 콘텐츠가 변경되지 않았다면 새로운 데이터를 다운로드하지 않고, 캐시를 재사용할 수 있도록 304 Not Modified 같은 응답을 보낼 수 있습니다.

5. force-cache: 캐시된캐시 된 복사본이 있으면, 상태에 관계없이 해당 복사본을 사용합니다. 캐시 된 복사본이 없을 경우에만 네트워크를 통해 데이터를 가져옵니다.

6. only-if-cached: 네트워크를 사용하지 않고, 현재 캐시에 있는 데이터만 사용합니다. 만약 적합한 캐시가 없다면, 요청은 실패합니다. 이 옵션은 mode가 same-origin일 때만 작동합니다.

Revalidating Data

Revalidating Data옵션은 캐시유지 시간을 초단위로 지정할수 있습니다.

fetch("https://...", { next: { revalidate: 3600 } });

이러한 옵션들을 fetch 요청의 cache 옵션에 설정함으로써, 웹 애플리케이션의 데이터 로딩 성능을 최적화하고, 네트워크 사용량을 조절할 수 있습니다. 각 옵션은 애플리케이션의 특정 요구사항과 콘텐츠의 캐싱 가능 여부에 따라 적절히 선택되어야 합니다.

홈화면
추가버튼 클릭
입력버튼 클릭
글입력 확인

{
  "topics": [
    {
      "id": 1,
      "title": "블랙핑크",
      "body": "블랙핑크 good!"
    },
    {
      "id": 2,
      "title": "아이브",
      "body": "아이브 good!"
    },
    {
      "id": 3,
      "title": "르세라핌",
      "body": "르세라핌 good!"
    },
    {
      "id": 4,
      "title": "뉴진스",
      "body": "뉴진스 good!"
    },
    {
      "id": 5,
      "title": "트와이스",
      "body": "트와이스 good!"
    },
    {
      "id": 6,
      "title": "레드벨벳",
      "body": "레드벨벳 good!"
    },
    {
      "id": 7,
      "title": "에스파",
      "body": "에스파 good!"
    },
    {
      "title": "아일릿",
      "body": "아일릿 good",
      "id": 8
    }
  ]  
}

[ 소스코드 확인 ]

layout.js

주의: 글을 입력 후 즉시 갱신된 모습을 확인하시려면 {cache:'no-store'} 캐시를 사용하지 않도록 설정해야 합니다.

import Link from "next/link";
import "./globals.css";

export const metadata = { //서버컴포넌트는 metadata를 사용가능
  title: "빌보드 차트",
  description: "최신 빌보드 차트 정보",
};

export default async function RootLayout({ children }) {
  const resp = await fetch("http://localhost:9999/topics", {cache:'no-store'});
  const rs = await resp.json();
  console.log(rs);
  return (
    <html>
      <body>
        <h1><Link href="/">빌보드 차트</Link></h1>
        <ol>
          {rs.map((topic)=>{
            return <li key={topic.id}><Link href={`/view/${topic.id}`}>{topic.title}</Link></li>
          })}
        </ol>
        {children}
        <ul>
          <a href="/create" className="action-link">추가</a>
          <a href="/create" className="action-link">수정</a>
          <a className="action-link">삭제</a>
        </ul>
      </body>
    </html>
  );
}

page.js

export default function Read(props) {
  return (
    <>
      <h2>HOME</h2>
    </>
  );
}

/view/[id]

주의: 글을 수정 후 즉시 갱신된 모습을 확인하시려면 {cache:'no-store'} 캐시를 사용하지 않도록 설정해야 합니다.

export default async function Read(props) {
  const resp = await fetch(`http://localhost:9999/topics/${props.params.id}`, {cache:'no-store'});
  const topic = await resp.json();
  return (
    <>
      <h2>{topic.title}</h2>
      {props.params.id}번째 팀을 소개합니다.<br/>
      {topic.body}
    </>
  );
}

/create/page.js

"use client"
import {useRouter} from "next/navigation";
export default function Create() {
    const router = useRouter();
    return (
      <>
        <h2>글입력</h2>
        <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(`/view/${lastid}`);
                    router.refresh();
                })
        }}>
            <p>
                <input type="text" name="title" placeholder="제목"/>
            </p>
            <p>
            <input type="text" name="body" placeholder="내용"/>
            </p>
            <p>
                <input type="submit" value="입력"/>
            </p>
        </form>
      </>
    );
  }

이상으로 JSON Server를 활용하여 Next.js에서 간단한 글 입력 기능을 구현하는 방법에 대해 알아보았습니다. JSON Server를 사용함으로써 복잡한 백엔드 설정 없이도 REST API를 모의로 구현하고, 프런트엔드 개발에 집중할 수 있습니다.

[ NextJs 시리즈 목차 ]

NextJs 01 : NextJs로 시작하는 웹 개발: 설치부터 브라우저 실행까지
NextJs 02: NextJs프로젝트 불필요한 파일제거
NextJs 03: NextJs서버 배포버전 빌드
NextJs 04: Link태그와 태그의 차이점을 이해하고 라우팅 설정까지
NextJs 05: 넥스트Js에서 정적 자원 사용하기
NextJs 06: npx와 json-server 사용하기
NextJs 07: 서버컴포넌트 vs 클라이언트컴포넌트
NextJs 08: Next.js를 활용한 동적 웹 콘텐츠 글보기 화면 실습
NextJs 09: Next.js 글입력 작성과 캐시처리
NextJs 10: 버튼 컴포넌트를 별도 파일로 분리 후 활성 비활성화 처리
NextJs 11: next.js글수정 useEffect
NextJs 12: next.js글삭제 처리 및 CRUD예제 다운로드
NextJs 13: env파일을 활용한 환경변수 설정