15
7

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

【React】制御コンポーネントと非制御コンポーネント

Posted at

はじめに

Reactのフォーム実装に関する「制御コンポーネント」と「非制御コンポーネント」についてまとめます。

制御コンポーネント

制御コンポーネントとは、フォームの入力値をReactコンポーネント(state)で扱うコンポーネントのことです。
メリットとしては、常に値にアクセスできるため、 ユーザが入力中にバリデーションを実施する 、といったリアクティブなフォームを作成できます。
デメリットとしては、入力値が更新されるたびに 再レンダリングが発生します

制御コンポーネントの実装例

import { useState } from "react";

export const Controlled = () => {
  const [inputValue, setInputValue] = useState<string>("");

  const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
    const value = e.target.value;

    // 入力中にもバリデーション
    if (value.length <= 10) {
      console.log("10文字以上で入力してください");
    }

    setInputValue(value);
  };

  const handleSubmitClick = () => {
    if (inputValue.length <= 10) {
      return;
    }
    console.log(inputValue);
  };

  return (
    <>
      <p>制御コンポーネント</p>
      <input type="text" value={inputValue} onChange={handleChange} />
      <button onClick={handleSubmitClick}>送信</button>
    </>
  );
};

非制御コンポーネントとは

非制御コンポーネントとは、フォームの入力値をDOMで扱うコンポーネントのことです。
useRefとinput要素のref属性を使用します。
メリットとしては、stateを経由しないため、入力値の更新毎に 再レンダリングが発生しません
デメリットとしては、必要なタイミング(submit時など)でDOMから入力値を取得するため、入力中にバリデーションを実施する、といった実装が難しいことが挙げられます。

非制御コンポーネントの実装例

import { useRef } from "react";

export const Uncontrolled = () => {
  const ref = useRef<HTMLInputElement>(null);

  const handleSubmitClick = () => {
    const value = ref.current?.value;

    // submit時にバリデーション
    if (value && value.length <= 10) {
      console.log("10文字以上で入力してください");
      return;
    }

    console.log(value);
  };

  return (
    <>
      <p>非制御コンポーネント</p>
      <input type="text" ref={ref} />
      <button onClick={handleSubmitClick}>送信</button>
    </>
  );
};

両者の比較とReact Hook Form

React公式では制御コンポーネントの使用を推奨しています。
理由としてはメリットで挙げた「入力中のバリデーション」など、できることが多いためです。
ただ、パフォーマンスへの懸念を考えると非制御コンポーネントを使いたくなるかと思います。

このような場合、React Hook Formを使うことで両者のメリットを享受できます。
React Hook Formは非制御コンポーネントを採用しており、ref属性にregisterを渡すことで、フォームの実装ができます。
基本的な使い方を以下の記事にまとめました。
React Hook FormとZodの基本的な使い方

また、なぜ非制御コンポーネントであるにも関わらず、リアクティブなフォームを実装できるのか?という疑問が出てくるかと思います。
これについては以下の記事に詳細にまとめられていたため、引用させていただきます。
React Hook Formは非制御コンポーネントからどうやって変更を検知しているのか

参考記事

採用のお知らせ

株式会社Relicでは、エンジニア・デザイナーを積極的に採用中です。
またRelicでは、地方拠点がありますので、U・Iターンも大歓迎です!🙌
少しでもご興味がある方は、Relic採用サイトからエントリーください!

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

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?