Next.js 13 - 12. 글생성

2023. 8. 31. 00:38Next.js/생활코딩

글 생성

이번에는 create 기능을 구현해보자. 이를 위해 create 폴더 내의 page.tsx 파일을 수정하면 된다. 중첩된 레이아웃을 설명하기 위해 이전에 만든 인위적인 layout.tsx 파일도 있는데 이건 이제 필요없어서 layout.tsx를 지워주고 page.tsx로 다시 시작하자.

 

만약 에러가 뜨면 일단 개발 서버를 껐다가 다시 켜보고 새로고침 해도 에러가 여전히 뜨면 .next를 지우고 다시 실행해보면 된다.

 

생성 기능을 위해 form을 만들어주자. 사용자가 어떤 값을 입력하고 create를 클릭했을 때 이벤트를 잡기 위해서는 form에 onSubmit 이 필요하다. 이건 사용자가 상호작용할 때 실행되는데 사용자와 상호작용하는 것은 서버 컴포넌트에서 다루지 않는다. 에러가 발생하게 되고, 이를 막기 위해 "use client"를 작성하고 클라이언트 컴포넌트로 바꿔주자!

 

그런데 웹은 서버쪽으로 데이터를 전송할 때 페이지가 바뀌게 된다. 이를 방지하기 위해 onSubmit에 이벤트에 preventDefault 함수를 호출하자. 그럼 기본 동작을 막게 되어 데이터를 입력하고 클릭해도 변화가 일어나지 않는다. 

 

이 다음 해야할 것은 title과 body의 값을 알아내는 것인데, 이벤트 객체의 target, 즉, form 태그의 name이 title인 것의 value를 구하고, body도 마찬가지로 구한다. name이 body인 태그의 값을 가져오도록 한다. 그럼 이제 서버랑 통신하는 코드를 갖다 놓으면 된다.

 

async await를 써도 되고 then을 써도 된다. 옵션을 설정해주고, fetch를 처리하면 결과적으로 새로운 글이 생성된다. 

 

이 다음에 해야할 것은 사용자가 보고 있는 페이지를 방금 생성한 라스트 아이디에 해당되는 글로 리다이렉션 시키는 것이다.

 

클라이언트 컴포넌트에서만 동작 가능한 useRouter를 통해 리다이렉션 시켜보자.

 

useRouter를 import 할 때 next/router로 하면 page router방식이고 next/navigation으로 해야 app router 방식이다. 

router를 이용해서 push 해주면 잘 이동한다. 

 

// /src/app/create/page.tsx


'use client';

import { useRouter } from 'next/navigation';

export default function Create() {
  const router = useRouter();
  return (
    <form
      onSubmit={(e: any) => {
        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

https://opentutorials.org/course/5098

 

Next.js 13 - 생활코딩

수업 개요 Next.js는 웹 애플리케이션을 빌드하고 배포하는 데 강력한 도구입니다. 이 도구를 활용하면 모던한 웹 앱을 빠르고 효율적으로 구축할 수 있습니다. 그럼 함께 미래의 웹 개발 패러다

opentutorials.org