🐦
Button の disabled だけで安心してはいけない
disabled
だけで安心していませんか?Reactでのボタン制御に潜む落とし穴
はじめに
Reactでボタンを一時的に無効化するには、disabled
属性を使うのが定番です。
例えば、送信中に二重クリックを防ぐための実装は次のようになります。
<button disabled={isSubmitting}>送信</button>
一見するとこれで十分に思えるかもしれません。
しかし、実はこの実装だけでは不十分なケースもあるのです。
disabled
は見た目だけの制御
disabled
属性を設定すれば、確かにUI上ではボタンが押せなくなります。
しかしこれはあくまでフロント側の見た目の制御にすぎません。
たとえば、ブラウザの開発者ツールを使えば、disabled
属性は簡単に解除できてしまいます。
document.querySelector('button')!.disabled = false;
このように、ユーザーが無効化されたはずのボタンを操作できてしまう可能性があるため、UIの制御だけでは不十分です。
より安全なフロントエンド実装
Reactでは、見た目の制御(disabled
)に加えて、処理の実行自体を制御するロジックを組み込むことで、より安全な実装が可能になります。
以下はその一例です。
import { useState } from "react";
export const SubmitButton: React.FC = () => {
const [isSubmitting, setIsSubmitting] = useState(false);
const handleClick = async () => {
if (isSubmitting) return; // 二重実行防止
setIsSubmitting(true);
try {
// 疑似的な非同期処理
await fakeApiRequest();
alert("送信完了");
} catch (error) {
console.error("送信エラー", error);
} finally {
setIsSubmitting(false);
}
};
return (
<button onClick={handleClick} disabled={isSubmitting}>
{isSubmitting ? "送信中..." : "送信"}
</button>
);
};
const fakeApiRequest = (): Promise<void> => {
return new Promise((resolve) => setTimeout(resolve, 2000));
};
実装のポイント
-
isSubmitting
による状態管理 -
handleClick
内での早期リターン(if (isSubmitting) return
) -
disabled
属性と連動させたUI制御
これにより、UIだけでなく処理の実行そのものを制御できるため、ユーザーによる操作や意図しない挙動をより確実に防げます。
おわりに
disabled
属性は便利ですが、それだけに頼るのは危険です。
Reactのようなフレームワークでは、UIとロジックを連携させることで、より堅牢なインターフェースが構築できます。
ボタン一つの挙動にも、セキュリティやユーザー体験への配慮が求められる時代です。
ぜひ一度、自身のコードを見直してみてください。
Discussion