点数
76点
感想
前編と同様に、JavaScript版に補章だけが追加されていた。
補章はただ型を指定しているだけなので、型指定がないとどうなるか、どうすると型チェックが実行されるか、なども書籍として本来は触れるべき点だと思う。
_app.jsのTypeScript化
- mv pages/_app.js pages/_app.tsx
- exportする関数の引数の型をAppPropsにする。
import type { AppProps } from "next/app";
import '../styles/globals.css';
export default function App({ Component, pageProps }: AppProps) {
return <Component {...pageProps} />
}
userディレクトリのTypeScript化
pages/user/register.jsのTypeScript化
- mv pages/user/register.js pages/user/register.tsx
- イベントハンドラの仮引数eの型はReact.FormEvent<HTMLFormElement>とする。
(Reactはnext-env.d.tsがあるのでインポート不要)] - 関数コンポーネントの型はNextPageとする。
(import {NextPage} from “next”;が必要)
import type { NextPage } from "next";
import { useState } from 'react';
const Register: NextPage = () => {
const [name, setName] = useState('');
const [email, setEmail] = useState('');
const [password, setPassword] = useState('');
const handleSubmit = async (e: React.FormEvent<HTMLFormElement>) => {
e.preventDefault();
try {
const response = await fetch('http://localhost:3000/api/user/register', {
method: 'POST',
headers: {
'Accrpt': 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify({
name: name,
email: email,
password: password,
})
});
const json = await response.json();
alert(json.msg);
} catch (err) {
alert('登録失敗');
}
};
return (
<>
<h1>ユーザー登録</h1>
<form onSubmit={handleSubmit}>
<p>name: <input type="text" name="name" value={name} onChange={e=>setName(e.target.value)} required /></p>
<p>email: <input type="text" name="email" value={email} onChange={e=>setEmail(e.target.value)} required/></p>
<p>password: <input type="text" name="password" value={password} onChange={e=>setPassword(e.target.value)} required/></p>
<p><button type="submit">登録</button></p>
</form>
</>
)
};
export default Register;
pages/user/login.jsのTypeScript化
- mv pages/user/login.js pages/user/login.tsx
- 修正内容はpages/user/register.tsxと全く同じ。
import type { NextPage } from "next";
import { useState } from 'react';
const Login: NextPage = () => {
const [email, setEmail] = useState('');
const [password, setPassword] = useState('');
const handleSubmit = async (e: React.FormEvent<HTMLFormElement>) => {
e.preventDefault();
try {
const response = await fetch('http://localhost:3000/api/user/login', {
method: 'POST',
headers: {
'Accrpt': 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify({
email: email,
password: password,
})
});
const json = await response.json();
localStorage.setItem('token', json.token); // 成功時のみ保存する場合は if (response.ok) {}で囲む必要あり
alert(json.msg);
} catch (err) {
alert('ログイン失敗');
}
};
return (
<>
<h1>ログイン</h1>
<form onSubmit={handleSubmit}>
<p>email: <input type="text" name="email" value={email} onChange={e=>setEmail(e.target.value)} required/></p>
<p>password: <input type="text" name="password" value={password} onChange={e=>setPassword(e.target.value)} required/></p>
<p><button type="submit">ログイン</button></p>
</form>
</>
)
};
export default Login;