0
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?

「フォームのクリアをしたのに、チェックボックスだけリセットされない!」問題の解決法✨

Posted at

はじめに

「リセットボタンを押したのに、なぜかチェックボックスだけ元の状態のままで変わらない…」

こんな経験はありませんか?Reactでフォームを実装していると、一見すべてのフォーム要素をリセットしたはずなのに、なぜかチェックボックスだけが頑固に元の状態を維持している…という状況に遭遇することがあります。

今回は、この「チェックボックスだけリセットされない問題」の原因と、シンプルな解決策について解説します。その鍵は、defaultCheckedcheckedプロパティの違いにあります。

問題の再現:チェックボックスだけがリセットされない...

まず、問題が発生するシンプルな例を見てみましょう

import React, { useState } from 'react';

function ProblemForm() {
  const [name, setName] = useState('');
  const [isAgree, setIsAgree] = useState(false);

  const handleReset = () => {
    setName('');
    setIsAgree(false);
    // ここでフォームをリセットしているつもり...
  };

  return (
    <form>
      <div>
        <label>名前:</label>
        <input
          type="text"
          value={name}
          onChange={(e) => setName(e.target.value)}
        />
      </div>
      
      <div>
        <label>
          <input
            type="checkbox"
            defaultChecked={isAgree}
            onChange={(e) => setIsAgree(e.target.checked)}
          /> 利用規約に同意する
        </label>
      </div>
      
      <button type="button" onClick={handleReset}>
        リセット
      </button>
    </form>
  );
}

このコードでは、リセットボタンをクリックすると次のことが起きます:

  1. setName('')で名前フィールドは空になります(UIも更新される)
  2. setIsAgree(false)でチェックボックスの状態は内部的にfalseになります
  3. しかし、チェックボックスのUI上の表示は変わりません!

これはdefaultCheckedプロパティの性質によるものです。

defaultCheckedとcheckedの本質的な違い

defaultChecked

defaultCheckedは、その名前が示す通り「デフォルト(初期)値のみを設定する」ためのプロパティです。

  • コンポーネントが最初にレンダリングされるときだけ適用される
  • 一度レンダリングされたら、ステートが変わっても再評価されない
  • HTMLのdefaultCheckedと同様の挙動をする

checked

一方、checkedは「現在の値」を表すプロパティです。

  • 常に現在の状態を反映する
  • 値が変わるたびに再評価され、UIも更新される
  • ReactによるUIの制御を可能にする

解決策:defaultCheckedからcheckedへの変更

問題を解決するには、defaultCheckedcheckedに変更するだけです:

import React, { useState } from 'react';

function FixedForm() {
  const [name, setName] = useState('');
  const [isAgree, setIsAgree] = useState(false);

  const handleReset = () => {
    setName('');
    setIsAgree(false);
  };

  return (
    <form>
      <div>
        <label>名前:</label>
        <input
          type="text"
          value={name}
          onChange={(e) => setName(e.target.value)}
        />
      </div>
      
      <div>
        <label>
          <input
            type="checkbox"
            checked={isAgree}  {/* defaultCheckedからcheckedに変更 */}
            onChange={(e) => setIsAgree(e.target.checked)}
          /> 利用規約に同意する
        </label>
      </div>
      
      <button type="button" onClick={handleReset}>
        リセット
      </button>
    </form>
  );
}

この変更により:

  1. setIsAgree(false)が実行されると、isAgreeステートがfalseに更新される
  2. checked={isAgree}は新しい値falseを反映する
  3. チェックボックスのUI状態も正しく更新される

いつdefaultCheckedを使い、いつcheckedを使うべきか?

defaultCheckedの使いどころ

  • フォームのリセットやプログラムによる変更が不要な場合
  • ユーザー入力のみでチェックボックスを制御する場合
  • 初期値のみを設定して、あとはユーザーに委ねる場合

checkedの使いどころ

  • フォームのリセット機能がある場合(今回のケース)
  • プログラムによる状態変更が必要な場合
  • 他のUI要素と連動して状態を変更する場合

チェックボックスのリセット問題をチェックするポイント

フォームのリセット機能を実装する際は、以下のポイントを確認しましょう:

  1. チェックボックスにはdefaultCheckedではなくcheckedを使用しているか
  2. ステートの更新とUI表示が連動しているか
  3. 全てのフォーム要素で統一した制御方法(制御コンポーネント)を使用しているか

まとめ

Reactでフォームを実装する際、チェックボックスだけがリセットされない問題はdefaultCheckedcheckedの違いを理解することで簡単に解決できます。

  • defaultChecked:初期レンダリング時のみ評価される
  • checked:常に現在の値を反映し、値が変わるとUIも更新される

プログラムによってチェックボックスの状態を変更する必要がある場合(フォームリセットなど)は、必ずcheckedプロパティを使用しましょう。これにより、内部状態とUI表示の同期が保たれ、ユーザーに一貫した体験を提供できます。

次回フォームを実装するときは、チェックボックスにdefaultCheckedcheckedのどちらを使うべきか、意識して選択してみてください。

0
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
0
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?