前回は、Firebase Authentication の機能を使って、React でユーザー登録機能を実装しました。

今回は、React でログイン機能を実装します。

まずは、pages フォルダに、Home.tsx と Login.tsx を作成します。

Login.tsx は、Signup.tsx のコードを基にします。

Home.tsx

import React from "react"

const Home = () => {
  return (
    <>
      <p>ホーム画面</p>
    </>
  )
}

export default Home

image2

Login.tsx

import React, { useState } from "react"
import {
  Avatar,
  Alert,
  Button,
  CssBaseline,
  TextField,
  Box,
  Typography,
  Container,
  Grid,
  Link,
} from "@mui/material"
import LockOutlinedIcon from "@mui/icons-material/LockOutlined"

export default function Login() {
  const [email, setEmail] = useState("")
  const [password, setPassword] = useState("")

  const handleSubmit = (event: React.FormEvent<HTMLFormElement>) => {
    event.preventDefault()
  }

  return (
    <Container component="main" maxWidth="xs">
      <CssBaseline />
      <Box
        sx={{
          marginTop: 8,
          display: "flex",
          flexDirection: "column",
          alignItems: "center",
        }}
      >
        <Avatar sx={{ m: 1, bgcolor: "secondary.main" }}>
          <LockOutlinedIcon />
        </Avatar>
        <Typography component="h1" variant="h5">
          ログイン
        </Typography>
        <Box component="form" onSubmit={handleSubmit} noValidate sx={{ mt: 1 }}>
          <TextField
            margin="normal"
            required
            fullWidth
            id="email"
            label="メールアドレス"
            name="email"
            autoComplete="email"
            autoFocus
            value={email}
            onChange={e => setEmail(e.target.value)}
          />
          <TextField
            margin="normal"
            required
            fullWidth
            name="password"
            label="パスワード"
            type="password"
            id="password"
            autoComplete="current-password"
            value={password}
            onChange={e => setPassword(e.target.value)}
          />
          <Button
            type="submit"
            fullWidth
            variant="contained"
            sx={{ mt: 3, mb: 2 }}
          >
            ログイン
          </Button>
          <Grid container>
            <Grid item xs>
              <Link href="#" variant="body2">
                パスワードを忘れた方
              </Link>
            </Grid>
            <Grid item>
              <Link href="#" variant="body2">
                アカウントをお持ちでない方
              </Link>
            </Grid>
          </Grid>
        </Box>
      </Box>
    </Container>
  )
}

image3

react-router-dom を使って、パスを設定します。

ターミナルでプロジェクトのディレクトリに移動し、npm install --save react-router-domを実行します。

ルートの設定方法は、以前紹介した、React Router DOM v6 で画面遷移する方法を参照ください。

function App() {
  return (
    <ThemeProvider theme={theme}>
      <BrowserRouter>
        <Routes>
          <Route path="/" element={<Home />} />
          <Route path="login" element={<Login />} />
          <Route path="signup" element={<Signup />} />
        </Routes>
      </BrowserRouter>
    </ThemeProvider>
  )
}

hooks フォルダの useAuth.ts に、useLoginを作成します。

また、useState を使って、ログインに成功した場合と失敗した場合の状態を管理します。

export const useLogin = () => {
  const [success, setSuccess] = useState(false)
  const [error, setError] = useState(null)

  const login = (email: string, password: string) => {
    setError(null)
    signInWithEmailAndPassword(fireauth, email, password)
      .then(() => {
        setSuccess(true)
      })
      .catch(err => {
        console.log(err.message)
        setError(err.message)
      })
  }

  return { success, error, login }
}

ログインに成功した場合は、ホーム画面へ遷移するよう、react-route-dom からuseNavigateをインポートします。

import { useNavigate } from "react-router-dom"

useLoginuseNavigateを設定しましょう。

また、少し遅れてホーム画面へ遷移するよう、setTimeoutを使用します。

export const useLogin = () => {
  const navigate = useNavigate()

  const [success, setSuccess] = useState(false)
  const [error, setError] = useState(null)

  const login = (email: string, password: string) => {
    setError(null)
    signInWithEmailAndPassword(fireauth, email, password)
      .then(() => {
        setSuccess(true)
        setTimeout(() => {
          navigate("/")
        }, 2000)
      })
      .catch(err => {
        console.log(err.message)
        setError(err.message)
      })
  }

  return { success, error, login }
}

useLoginを Login.tsx へ接続します。

const { login, success, error } = useLogin()

handleSubmitloginを設定します。

login内には、emailpasswordを指定しましょう。

const handleSubmit = (event: React.FormEvent<HTMLFormElement>) => {
  event.preventDefault()
  login(email, password)
}

ログインに成功した場合と、失敗した場合にメッセージを表示するようにします。

{
  error && <Alert severity="error">ログインできませんでした</Alert>
}
{
  success && <Alert severity="success">ログインしました</Alert>
}

『アカウントをお持ちでない方』をクリックすると、ユーザー登録画面へ遷移するようにします。

<Link href="signup" variant="body2">
  アカウントをお持ちでない方
</Link>

image4

また、Signup.tsx にログイン画面へ遷移できるよう、リンクを設定します。

<Grid container sx={{ justifyContent: "center" }}>
  <Grid item>
    <Link href="login" variant="body2">
      ログインはこちら
    </Link>
  </Grid>
</Grid>

image5

では、ログイン画面へ戻って、実際にログインしてみましょう。

image6

まずは、パスワードが間違っている状態でログインすると、

image7

『ログインできませんでした』と表示されました。

では、先日ユーザー登録したメールアドレスとパスワードを使ってログインしてみます。

image8

image9

『ログインしました』と表示され、ホーム画面へ遷移することができました。

次回は、React でログアウト機能を実装します。

ブログ一覧