技術学習記録 201214

前回の記事 で書いたコードを改善していく。

多分初心者向けにかんたんにしようとしてくれていて、フォーム周りをReact系技術なしで書かれていたので、それをReact + TypeScriptぽくしていく。


目次

問題のコード

app/memos/components/MemoForm.tsx

1
2
3
4
5
6
7
8
9
10
11
12
13
14
const MemoForm = ({ initialValues, onSubmit }: MemoFormProps) => {
return (
<form
onSubmit={(event) => {
event.preventDefault()
onSubmit(event)
}}
>
<input placeholder="タイトル" defaultValue={initialValues.title} />
<textarea placeholder="本文" defaultValue={initialValues.body} />
<button>Submit</button>
</form>
)
}

ここでonSubmitでeventを渡した結果、

app/memos/pages/memos/new.tsx

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<MemoForm
initialValues={{}}
onSubmit={async (event) => {
if (currentUser) {
try {
const memo = await createMemoMutation({
data: {
title: event.target[0].value,
body: event.target[1].value,
user: { connect: { id: currentUser.id } },
},
})
alert("succress")
router.push(`/memos/${memo.id}`)
} catch (error) {
alert("error")
console.log(error)
}
}
}}
/>

ここで参照する event.target[0].value がany型になってしまっている。
これをいい感じに修正したい。

パッと思いつく改善をやってみる

とりあえず自分が持ってる知識だけでぱぱっと解決してみようと思う。

app/memos/components/MemoForm.tsx

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
import React, { useState } from "react"
import {MemoCreateFormInput} from '../pages/memos/new'

type MemoFormProps = {
initialValues: any
onSubmit: (props: MemoCreateFormInput) => void
}

const MemoForm = ({ initialValues, onSubmit }: MemoFormProps) => {
const [title, setTitle] = useState('')
const [body, setBody] = useState('')

return (
<form
onSubmit={(event) => {
event.preventDefault()
onSubmit({title: title, body: body})
}}
>
<input placeholder="タイトル" defaultValue={initialValues.title} onChange={(event) => {setTitle(event.target.value)}} />
<textarea placeholder="本文" defaultValue={initialValues.body} onChange={(event) => {setBody(event.target.value)}}/>
<button>Submit</button>
</form>
)
}

export default MemoForm

useStateを使って入力値を取得し、それをonSubmit関数に渡す。

app/memos/pages/memos/new.tsx

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
// 中略

export type MemoCreateFormInput = {
title: string,
body: string
}

const NewMemoPage: BlitzPage = () => {
const router = useRouter()
const [createMemoMutation] = useMutation(createMemo)
const currentUser = useCurrentUser()

return (
<div>
<h1>Create New Memo</h1>

<MemoForm
initialValues={{}}
onSubmit={async (props: MemoCreateFormInput) => {
if (currentUser) {
try {
const memo = await createMemoMutation({
data: {
title: props.title,
body: props.body,
user: { connect: { id: currentUser.id } },
},
})
alert("succress")
router.push(`/memos/${memo.id}`)
} catch (error) {
alert("error")
console.log(error)
}
}
}}

//中略

onSubmitで要求する引数はこっちでtypeを定義しておき、あとはその引数の中身を使ってcreateMemoMutationする。

これでとりあえずどこにもany型が登場しない形になった。

ところで、この状態でcommitしようとするとterminalに次のエラーが出た。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
app/memos/pages/memos/[memoId]/edit.tsx:29:32 - error TS2339: Property 'target' does not exist on type 'MemoCreateFormInput'.

29 title: event.target[0].value,
~~~~~~

app/memos/pages/memos/[memoId]/edit.tsx:30:31 - error TS2339: Property 'target' does not exist on type 'MemoCreateFormInput'.

30 body: event.target[1].value,
~~~~~~


Found 2 errors.

rhusky > pre-push hook failed (add --no-verify to bypass)
error: failed to push some refs to 'git@github.com:sKawashima/blitz-memo.git'

edit側のコンポーネントで要求しているパラメータがformのコンポーネントで指定しているpropsにないことによるエラー。
エラーで教えてくれるの嬉しい。
ので、とりあえず直していく。

といっても一瞬だった。

app/memos/pages/memos/[memoId]/edit.tsx

1
2
3
4
5
6
7
8
9
10
11
12
13
<MemoForm
initialValues={memo}
onSubmit={async (props) => {
if (currentUser) {
try {
const updated = await updateMemoMutation({
where: { id: memo.id },
data: {
title: props.title,
body: props.body,
user: { connect: { id: currentUser.id } },
},
})

よく考えたら app/memos/components/MemoForm.tsxMemoCreateFormInput importしなくても保管効くよなあ…って思った。
VSCodeに感謝。

次回予告:React Final Form を使ってみる

と書いてみたけど、どうなんだろう。
ざっくりドキュメント見てみたけど現状とどれくらい差が出るのかぴんと来ていない。

でもまあ、BlitzのRecommendだったし一応触ってみることにしようかな。

今日はここまで。

余談

参考にしているサイトには続編が来ていることを確認。

タグ「Blitz.js」の記事一覧 - bagelee(ベーグリー)

早く追いつこう。