📑

Nextjs×Prisma×SQLiteでupdateする方法(その1)

2022/12/22に公開約4,700字

アップデートをするにはまずアップデートしたい記事のIDを取得する必要があります。
前回readで取得した方法と同じです。
localhost:3000/post/edit/[id].tsxとして、idを取得します。

./pages/post/edit/[id].tsx
import prisma from "@utils/prisma"
import { useState } from "react"
import { Post } from "@utils/types"
import Router from "next/router"

export default function Edit({post}:{post:Post}) {
    const [id,setId] = useState(`${post.id}`)
    const [title,setTitle] = useState(`${post.title}`)
    const [content,setContent] = useState(`${post.content}`)
    const updatePost = async (e: React.SyntheticEvent) => {
        e.preventDefault()
        try {
            const body = { id, title, content }
            await fetch("/api/edit",{
                method: "POST",
                body: JSON.stringify(body)
            })
            await Router.push("/post")
        }catch(err) {
            console.log(err)
        }
    }
    return (
        <form>
          <label htmlFor="title">タイトル:</label>
          <input id="title" type="text" onChange={(e)=>setTitle(e.target.value)} value={title}/>
          <label htmlFor="content">内容:</label>
          <textarea id="content" onChange={(e)=>setContent(e.target.value)} value={content}/>
          <button onClick={updatePost}>編集</button>
        </form>
    )
}
export async function getServerSideProps({params}:{params:{id:number}}) {
    const post = await prisma.post.findUnique({
        where: {
            id: Number(params.id)
        }
    })
    return {
        props: {
            post: post 
        }
    }
}

getServerSideProps内で編集したいデータのIDを取得して、そのデータをpostに入れています。

export async function getServerSideProps({params}:{params:{id:number}}) {
    const post = await prisma.post.findUnique({
        where: {
            id: Number(params.id)
        }
    })
    return {
        props: {
            post: post 
        }
    }
}

今回はcreateではなくupdateなので初期値があるので、id,title,contentに初期値を入れています。

const [id,setId] = useState(`${post.id}`)
const [title,setTitle] = useState(`${post.title}`)
const [content,setContent] = useState(`${post.content}`)

この初期値がformに最初から入っている状態になります。

return (
        <form>
          <label htmlFor="title">タイトル:</label>
          <input id="title" type="text" onChange={(e)=>setTitle(e.target.value)} value={title}/>
          <label htmlFor="content">内容:</label>
          <textarea id="content" onChange={(e)=>setContent(e.target.value)} value={content}/>
          <button onClick={updatePost}>編集</button>
        </form>
    )

適当にタイトルと内容を編集してから編集ボタンを押すと/api/editにデータが送信されます。今回はcreateと違ってidが決まっているのでidも送信しています。

const updatePost = async (e: React.SyntheticEvent) => {
        e.preventDefault()
        try {
            const body = { id, title, content }
            await fetch("/api/edit",{
                method: "POST",
                body: JSON.stringify(body)
            })
            await Router.push("/post")
        }catch(err) {
            console.log(err)
        }
}

/api/editに送信されたデータをupdateで更新します。

./pages/api/edit
import prisma from "@utils/prisma"
import { NextApiRequest, NextApiResponse } from "next"

export default async function createPost(req:NextApiRequest,res:NextApiResponse) {
    const JSONdata = JSON.parse(req.body)
    const result = await prisma.post.update({
        where: {
            id: Number(JSONdata.id)
        },
        data: {
            title: JSONdata.title,
            content: JSONdata.content,
            published: true,
        },
    })
    res.json(result)
}

例えば、idが58のデータを編集したい場合、host:3000/post/edit/58と叩くと編集画面に入ります。

タイトルと内容が最初から入っていることが分かります。

適当にタイトルと内容を編集して編集ボタンを押すと編集されたことが確認できます。

今のままだと、編集したいデータのidのurlを手動で叩かないといけないので、全データ一覧のところに編集画面へのリンクを貼ります。

./pages/post/index.tsx
import prisma from "@utils/prisma"
import Link from "next/link"
import { Post } from "@utils/types"

export default function Home({posts}:{posts:Post[]}) {
  return(
    <ul>
      {
        posts.map((post:Post)=>(
          <li key={post.id}>
              <p>{post.id}</p>
              <p>{post.title}</p>
              <p>{post.content}</p>
              <Link href={`/post/${post.id}`}>詳細</Link>
              <Link href={`/post/edit/${post.id}`}>編集</Link>
          </li>
        ))
      }
    </ul>
  )
}

export async function getServerSideProps() {
  const posts = await prisma.post.findMany()
  return {
    props: {
      posts:posts,
    }
  }
}

これでCRUDのD以外ができました。残すところdeleteのみです。
次回はdeleteをしてみたいと思います。

Discussion

ログインするとコメントできます