LoginSignup
2
2

More than 1 year has passed since last update.

react-hook-formを使った動的アンケートフォームの作成

Posted at

アンケートアプリの作成の作成中、質問の回答結果によって次の質問が表示される動作を実装するのに苦戦したので書き留めておきます。

実装したいこと

Q1もしくはQ2の回答でラジオボタンの「はい」を選択した場合のみ、Q3が表示されるようにしたい。どちらの問いにも「いいえ」と「わからない」を選択した時は何も変化しない。

結果

react-hook-formの'watch'を使うことで、ラジオボタンの選択した結果を条件に定義することができ、実装することができた。
https://react-hook-form.com/jp/api#watch

まずは、ラジオボタンの選択結果を変数に入れる。


export default function Home() {
  const {
     register,
     watch,
     handleSubmit,
     formState: { errors },
     control
     } = useForm()

  const watchIsLearning = watch("isLearning");
  const watchWasLearning = watch("wasLearning");

次にその変数を使って条件分岐し、決められた条件の場合に動作が起こるようにする。


    { ( watchIsLearning === "true" || watchWasLearning === "true" ) &&

条件付きレンダリングとして論理 && 演算子を用いることが多いそう。
今回は2つの質問のどちらかがtrueであれば良いので、or ( || )を使った。
その場合は || と && では && の方が優先して実行されるようなので、()を使用して || を優先するように書いたところ成功した。

全体コード

import { useForm, Controller } from 'react-hook-form';
import { Container, Input, TextField } from "@material-ui/core";

export default function Home() {
  const {
     register,
     watch,
     handleSubmit,
     formState: { errors },
     control
     } = useForm()

  const watchIsLearning = watch("isLearning");
  const watchWasLearning = watch("wasLearning");

  return (
    <>
      <Container>
        <h1>プログラミング学習に関するアンケート</h1>

        <form onSubmit={handleSubmit(onSubmit)}>

          <div>
            <span>Q1.現在、プログラミング学習をしていますか?</span>
            <input id="isLearning1" {...register("isLearning", { required: true })}
              name="isLearning"
              type="radio"
              value="true"
            />
            <label htmlFor="isLearning1">はい</label>

            <input id="isLearning2" {...register("isLearning", { required: true })}
              name="isLearning"
              type="radio"
              value="false"
            />
            <label htmlFor="isLearning2">いいえ</label>

            <input id="isLearning3" {...register("isLearning", { required: true })}
              name="isLearning"
              type="radio"
              value="null"
            />
            <label htmlFor="isLearning3">わからない</label>
            {
              errors.isLearning &&
              <span>このフィールドは回答必須です。</span>
            }
          </div>

          <div>
            <span>Q2.これまでに、プログラミングを学習したことがありますか?</span>
            <input id="wasLearning1" {...register("wasLearning", { required: true })}
              name="wasLearning"
              type="radio"
              value="true"
            />
            <label htmlFor="wasLearning1">はい</label>

            <input id="wasLearning2" {...register("wasLearning", { required: true })}
              name="wasLearning"
              type="radio"
              value="false"
            />
            <label htmlFor="wasLearning2">いいえ</label>

            <input id="wasLearning3" {...register("wasLearning", { required: true })}
              name="wasLearning"
              type="radio"
              value="null"
            />
            <label htmlFor="wasLearning3">わからない</label>
            {
              errors.wasLearning &&
              <span>このフィールドは回答必須です。</span>
            }
          </div>

          { ( watchIsLearning === "true" || watchWasLearning === "true" ) &&

                <div>
                  <label htmlFor="learningLanguage">Q3.これまで学習したことのあるプログラミング言語をすべて教えてください。</label>
                    <Controller
                        name="learningLanguage"
                        defaultValue=""
                        control={control}
                        render={({ field: { value, onChange } }) => (
                          <TextField
                            value={value}
                            onChange={onChange}
                            fullWidth
                            margin="normal"
                            rows={3}
                            multiline
                            variant="outlined"
                          />
                        )}
                      />
                </div>
          }

        <input type="submit" value="アンケートを提出する" />
        </form>
      </Container>

    </>
  )
}

完成画面

<初期画面>
image.png

<回答選択後画面>
image.png

2
2
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
2
2