1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【React / TypeScript】MUIとreact-hook-formを使ったフォームの作成

Posted at

概要

Material UI(MUI)React Hook Formを使ったフォームを私なりに作ってみたので、備忘録として残します。
ログインフォームを題材としてフォームを作ります。

前提

  • Reactがインストールされていること
  • MUIとReact Hook Formがインストールされていること
npm i @mui/material @emotion/react @emotion/styled react-hook-form

サンプルコード(最小限)

React Hook Formが機能する必要最小限のコードです。
スタイルはつけておらず、これをもとにカスタマイズしていきます。

"use client"
import { Button, TextField } from "@mui/material"
import React from "react"
import { SubmitHandler, useForm } from "react-hook-form"

type Input = {
  example: string
}

const page = () => {
  const { register, handleSubmit } = useForm<Input>()
  const onSubmit: SubmitHandler<Input> = (data) => console.log(data);
  return (
    <>
      <form onSubmit={handleSubmit(onSubmit)}>
        <TextField
          id="outlined-basic"
          label="Outlined"
          {...register("example")}
        />
        <div>
          <Button type='submit' variant="contained">Contained</Button>
        </div>
      </form>
    </>
  )
}

export default page

image.png
入力された値はonSubmitのdataに渡されます。
image.png

完成したもの

"use client"
import { Box, Button, Container, Paper, TextField } from "@mui/material"
import React from "react"
import { SubmitHandler, useForm } from "react-hook-form"

type Input = {
  email: string,
  password: string
}

const page = () => {
  const { register, handleSubmit } = useForm<Input>()
  const onSubmit: SubmitHandler<Input> = (data) => console.log(data);
  return (
    <>
      <Container sx={{ display: "flex", alignItems: "center", justifyContent: "center", height: "100vh" }}>
        <Paper elevation={3} sx={{ width: "600px", padding: 4 }}>

          <Box sx={{ textAlign: "center", fontSize: "24px", fontWeight: "bold" }}>ログイン</Box>
          <form onSubmit={handleSubmit(onSubmit)}>
            <TextField
              fullWidth
              id="outlined-basic"
              label="Email"
              type="email"
              margin="normal"
              {...register("email")}
            />
            <TextField
              fullWidth
              id="outlined-basic"
              label="password"
              type="password"
              margin="normal"
              {...register("password")}
            />
            <div>
              <Button type='submit' variant="contained" sx={{ marginTop: "16px" }}>ログイン</Button>
            </div>
          </form>
          
        </Paper>
      </Container>
    </>
  )
}

export default page

image.png
私的にはシンプルなフォームが出来上がったかと思います。
ただ、入力されていなかった場合のエラー処理がまだ実装していません。
そこでReact Hook FormのuseFormにあるformStateを使っていきます。
また、MUIのTextFieldはエラー時のプロパティ(errorとhelperText)を用意しているようなのでこれと組み合わせて使っていきます。

"use client"
import { Box, Button, Container, Paper, TextField } from "@mui/material"
import React from "react"
import { SubmitHandler, useForm } from "react-hook-form"

type Input = {
  email: string,
  password: string
}

const page = () => {
  const { register, handleSubmit, formState: { errors }} = useForm<Input>()
  const onSubmit: SubmitHandler<Input> = (data) => console.log(data);
  return (
    <>
      <Container sx={{ display: "flex", alignItems: "center", justifyContent: "center", height: "100vh" }}>
        <Paper elevation={3} sx={{ width: "600px", padding: 4 }}>

          <Box sx={{ textAlign: "center", fontSize: "24px", fontWeight: "bold" }}>ログイン</Box>
          <form onSubmit={handleSubmit(onSubmit)}>
            <TextField
              fullWidth
              id="outlined-basic"
              label="Email"
              type="email"
              margin="normal"
              {...register("email", { required: true })}
              error={errors.email ? true : false }
              helperText={errors.email ? "Email is required" : ""}
            />

            <TextField
              fullWidth
              id="outlined-basic"
              label="Password"
              type="password"
              margin="normal"
              {...register("password", { required: true })}
              error={errors.password ? true : false }
              helperText={errors.password ? "Password is required" : ""}
            />
            <div>
              <Button type='submit' variant="contained" sx={{ marginTop: "16px" }}>ログイン</Button>
            </div>
          </form>
          
        </Paper>
      </Container>
    </>
  )
}

export default page

image.png
image.png

ログインボタンが押されて入力欄が空だったときはエラーが表示されるようになりました。

まとめ

MUIとreact-hook-formを使って簡単なフォームを作ってみました。
理解の助けになっていただければ幸いです。
ただ、調べているうちにMUIとreact-hook-formを複合したライブラリがあるようで、これを試してみたいと思います。

参考・引用

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?