<input>
組み込みのブラウザ <input>
コンポーネント は、さまざまな種類のフォーム入力をレンダーすることができます。
<input />
リファレンス
<input>
入力を表示するには、組み込みのブラウザ <input>
コンポーネントをレンダーします。
<input name="myInput" />
Props
<input>
は全ての共通要素である props をサポートしています。
以下の props を渡すことで、入力を制御することができます。
checked
: ブール値。チェックボックス入力またはラジオボタンの場合、選択されているかどうかを制御します。value
: 文字列。テキスト入力の場合、そのテキストを制御します。(ラジオボタンの場合は、フォームデータを指定します。)
これらのいずれかを渡す場合、渡された値を更新する onChange
ハンドラも渡す必要があります。
以下の <input>
の props は、制御されていない入力にのみ関連しています。
defaultChecked
: ブール値。type="checkbox"
およびtype="radio"
の入力の初期値を指定します。defaultValue
: 文字列。テキスト入力の初期値を指定します。
以下の <input>
props は、制御されていない入力と制御された入力の両方に関連します。
accept
: 文字列。type="file"
の入力によって受け取るファイルの種類を指定します。alt
: 文字列。type="image"
の入力によって代替画像テキストを指定します。capture
: 文字列。type="file"
入力によってキャプチャされたメディア(マイク、ビデオ、またはカメラ)を指定します。autoComplete
: 文字列。可能なオートコンプリート動作の 1 つを指定します。autoFocus
: ブール値。true
の場合、React はマウント時にその要素をフォーカスします。dirname
: 文字列。要素の文字方向性に対するフォームフィールド名を指定します。disabled
: ブール値。true
の場合、入力はインタラクティブでなく、淡色表示されます。children
:<input>
は子要素を受け取りません。form
: 文字列。この入力が属する<form>
のid
を指定します。省略された場合、最も近い親フォームが対象となります。formAction
: 文字列。type="submit"
およびtype="image"
の親要素である<form action>
を上書きします。formEnctype
: 文字列。type="submit"
およびtype="image"
の親要素である<form enctype>
を上書きします。formMethod
: 文字列。type="submit"
およびtype="image"
の親要素である<form method>
を上書きします。formNoValidate
: 文字列。type="submit"
およびtype="image"
の親要素である<form noValidate>
を上書きします。formTarget
: 文字列。type="submit"
およびtype="image"
の親要素である<form target>
を上書きします。height
: 文字列。type="image"
の画像の高さを指定します。list
: 文字列。オートコンプリートオプションを持つ<datalist>
のid
を指定します。max
: 数値。数値および日時入力の最大値を指定します。maxLength
: 数値。テキストおよびその他の入力の最大文字数を指定します。min
: 数値。数値および日時入力の最小値を指定します。minLength
: 数値。テキストおよびその他の入力の最小文字数を指定します。multiple
: ブール値。<type="file"
およびtype="email"
に複数の値を許可するかどうかを指定します。name
: 文字列。フォームで送信された入力の名前を指定します。onChange
:イベント
ハンドラ関数。制御された入力に必要です。ユーザが入力の値を変更するとすぐに起動します(例えば、キーストロークごとに起動します)。ブラウザの入力
のイベントと同じように作動します。onChangeCapture
: キャプチャフェーズで起動するonChange
のバージョン。onInput
:イベント
ハンドラ関数。ユーザが値を変更するとすぐに起動します。歴史的な理由から、React では同様に動作するonChange
を代わりに使用するのが慣用的です。onInputCapture
: キャプチャフェーズで起動するonInput
のバージョン。onInvalid
:イベント
ハンドラ 関数。フォーム送信時の入力の検証に失敗した場合に起動します。組み込みのinvalid
イベントとは異なり、React のonInvalid
イベントはバブリングします。onInvalidCapture
: キャプチャフェーズで起動するonInvalid
のバージョン。onSelect
:イベント
ハンドラ 関数。<input>
内の選択が変更された後に起動します。React はonSelect
イベントを拡張して、空の選択および編集時(選択に影響する可能性がある場合)にも起動します。onSelectCapture
: キャプチャフェーズで起動するonSelect
のバージョン。pattern
: 文字列。value
が一致する必要があるパターンを指定します。placeholder
: 文字列。入力値が空の場合は淡色で表示されます。readOnly
: ブール値。true
の場合、ユーザは入力を編集できません。required
: ブール値。true
の場合、フォームを送信するには値を指定する必要があります。size
: 数値。幅を設定と似ていますが、単位はコントロールによって異なります。src
: 文字列。type="image"
入力の、画像ファイルを指定します。step
: 正数または'任意の'
文字列。有効な値間の距離を指定します。type
: 文字列。入力タイプの 1 つ。width
: 文字列。type="image"
入力の画像の幅を指定します。
注意事項
- チェックボックスには
value
(またはdefaultValue
) ではなく、checked
(またはdefaultChecked
) が必要です。 - テキスト入力が文字列
value
プロパティを受け取った場合、それは 制御されているものとして扱われます。 - チェックボックスまたはラジオボタンがブール値の
checked
プロパティを受け取った場合、それは 制御されているものとして扱われます。 - 入力を、同時に制御、非制御コンポーネントの両方にすることはできません。
- 入力を、その存続期間内に、制御、非制御で切り替えることはできません。
- すべての制御された入力には、その前の値を同期的に更新する
onChange
イベントハンドラが必要です。
使用法
様々なタイプの入力を表示する
入力を表示するには、<input>
コンポーネントをレンダーします。デフォルトではテキスト入力になります。チェックボックスの場合は type="checkbox"
、ラジオボタンの場合は type="radio"
、または他の入力タイプのいずれかを渡すことができます。
export default function MyForm() { return ( <> <label> Text input: <input name="myInput" /> </label> <hr /> <label> Checkbox: <input type="checkbox" name="myCheckbox" /> </label> <hr /> <p> Radio buttons: <label> <input type="radio" name="myRadio" value="option1" /> Option 1 </label> <label> <input type="radio" name="myRadio" value="option2" /> Option 2 </label> <label> <input type="radio" name="myRadio" value="option3" /> Option 3 </label> </p> </> ); }
入力にラベルを付ける
通常、すべての <input>
を <label>
タグ内に配置します。これにより、ブラウザに対してこのラベルがその入力に関連付けられていることを伝えます。ユーザがラベルをクリックすると、ブラウザは自動的に入力にフォーカスを当てます。これはアクセシビリティにも重要です。スクリーンリーダーは、ユーザが関連付けられた入力にフォーカスしたとき、ラベルのキャプションを読み上げます。
<input>
を <label>
にネストできない場合は、同じ ID を <input id>
と <label htmlFor>
に渡すことで関連付けます。また、同じコンポーネントの複数のインスタンス間の競合を避けるために、useId
. を使用してそのような ID を生成します。
import { useId } from 'react'; export default function Form() { const ageInputId = useId(); return ( <> <label> Your first name: <input name="firstName" /> </label> <hr /> <label htmlFor={ageInputId}>Your age:</label> <input id={ageInputId} name="age" type="number" /> </> ); }
入力の初期値を指定する
オプションで、入力の初期値を指定することができます。テキスト入力の場合は、defaultValue
として文字列を渡します。チェックボックスとラジオボタンの場合は、代わりに defaultChecked
ブール値を使用して初期値を指定します。
export default function MyForm() { return ( <> <label> Text input: <input name="myInput" defaultValue="Some initial value" /> </label> <hr /> <label> Checkbox: <input type="checkbox" name="myCheckbox" defaultChecked={true} /> </label> <hr /> <p> Radio buttons: <label> <input type="radio" name="myRadio" value="option1" /> Option 1 </label> <label> <input type="radio" name="myRadio" value="option2" defaultChecked={true} /> Option 2 </label> <label> <input type="radio" name="myRadio" value="option3" /> Option 3 </label> </p> </> ); }
フォーム送信時に入力値を読み取る
入力の周囲に、<form>
を追加し、内部に <button type="submit">
を配置します。これにより、<form onSubmit>
のイベントハンドラが呼び出されます。デフォルトでは、ブラウザはフォームデータを現在の URL に送信し、ページを更新します。e.preventDefault()
を呼び出すことで、その動作を防ぐことができます。new FormData(e.target)
を使用してフォームデータを読み込みます。
export default function MyForm() { function handleSubmit(e) { // Prevent the browser from reloading the page e.preventDefault(); // Read the form data const form = e.target; const formData = new FormData(form); // You can pass formData as a fetch body directly: fetch('/some-api', { method: form.method, body: formData }); // Or you can work with it as a plain object: const formJson = Object.fromEntries(formData.entries()); console.log(formJson); } return ( <form method="post" onSubmit={handleSubmit}> <label> Text input: <input name="myInput" defaultValue="Some initial value" /> </label> <hr /> <label> Checkbox: <input type="checkbox" name="myCheckbox" defaultChecked={true} /> </label> <hr /> <p> Radio buttons: <label><input type="radio" name="myRadio" value="option1" /> Option 1</label> <label><input type="radio" name="myRadio" value="option2" defaultChecked={true} /> Option 2</label> <label><input type="radio" name="myRadio" value="option3" /> Option 3</label> </p> <hr /> <button type="reset">Reset form</button> <button type="submit">Submit form</button> </form> ); }
状態変数を使用して入力要素を制御する
<input />
のような入力は制御されません。<input defaultValue="Initial text" />
のように初期値を渡す場合でも、JSX は初期値を指定するだけで、現在の値を制御するものではありません。
controlled 入力をレンダーするには、それに value
プロパティを渡します。(チェックボックスやラジオの場合は、checked
) React は、常に指定した value
を入力が持つように強制します。通常、状態変数を宣言することによってこれを行います。
function Form() {
const [firstName, setFirstName] = useState(''); // Declare a state variable...
// ...
return (
<input
value={firstName} // ...force the input's value to match the state variable...
onChange={e => setFirstName(e.target.value)} // ... and update the state variable on any edits!
/>
);
}
制御された入力要素は、状態が必要な場合に意味があります。例えば、編集のたびに UI を再レンダーする必要がある場合などです。
function Form() {
const [firstName, setFirstName] = useState('');
return (
<>
<label>
First name:
<input value={firstName} onChange={e => setFirstName(e.target.value)} />
</label>
{firstName !== '' && <p>Your name is {firstName}.</p>}
...
また、制御された入力は、入力状態を調整するための複数の方法(例えば、ボタンをクリックすることによってなど)を提供したい場合にも役立ちます。
function Form() {
// ...
const [age, setAge] = useState('');
const ageAsNumber = Number(age);
return (
<>
<label>
Age:
<input
value={age}
onChange={e => setAge(e.target.value)}
type="number"
/>
<button onClick={() => setAge(ageAsNumber + 10)}>
Add 10 years
</button>
制御されたコンポーネントに渡す value
は、undefined
や null
であってはなりません。初期値を空にしたい場合(例えば、以下の firstName
フィールドのような場合)、状態変数を空の文字列(''
)で初期化してください。
import { useState } from 'react'; export default function Form() { const [firstName, setFirstName] = useState(''); const [age, setAge] = useState('20'); const ageAsNumber = Number(age); return ( <> <label> First name: <input value={firstName} onChange={e => setFirstName(e.target.value)} /> </label> <label> Age: <input value={age} onChange={e => setAge(e.target.value)} type="number" /> <button onClick={() => setAge(ageAsNumber + 10)}> Add 10 years </button> </label> {firstName !== '' && <p>Your name is {firstName}.</p> } {ageAsNumber > 0 && <p>Your age is {ageAsNumber}.</p> } </> ); }
キーストロークごとの再レンダーを最適化する
制御された入力を使用する場合、キーストロークごとに状態が更新されます。状態を含むコンポーネントが大きなツリーを再レンダーすると、速度が遅くなる可能性があります。再レンダーのパフォーマンスを最適化する方法はいくつかあります。
例えば、キーストロークごとにすべてのページコンテンツを再レンダーするフォームがあるとします。
function App() {
const [firstName, setFirstName] = useState('');
return (
<>
<form>
<input value={firstName} onChange={e => setFirstName(e.target.value)} />
</form>
<PageContent />
</>
);
}
<PageContent />
は入力の状態に依存しないため、入力の状態を独自のコンポーネントに移動できます。
function App() {
return (
<>
<SignupForm />
<PageContent />
</>
);
}
function SignupForm() {
const [firstName, setFirstName] = useState('');
return (
<form>
<input value={firstName} onChange={e => setFirstName(e.target.value)} />
</form>
);
}
これにより、キーストロークごとに SignupForm
のみが再レンダーされるため、パフォーマンスが大幅に向上します。
再レンダーを回避する方法がない場合(例えば、PageContent
が検索入力の値に依存する場合)、useDeferredValue
を使用することで、大規模な再レンダーの途中でも、制御された入力の応答性を維持できます。
トラブルシューティング
テキストを入力しても更新されない
value
を指定して入力をレンダーし、onChange
を指定しないと、コンソールにエラーが表示されます。
// 🔴 Bug: controlled text input with no onChange handler
<input value={something} />
value
prop to a form field without an onChange
handler. This will render a read-only field. If the field should be mutable use defaultValue
. Otherwise, set either onChange
or readOnly
.エラーメッセージが示すように、初期値を指定したいだけの場合は、代わりに defaultValue
を渡してください。
// ✅ Good: uncontrolled input with an initial value
<input defaultValue={something} />
状態変数を使用してこの入力を制御したい場合は、onChange
ハンドラを指定します。
// ✅ Good: controlled input with onChange
<input value={something} onChange={e => setSomething(e.target.value)} />
値を意図的に読み取り専用にする場合は、エラーを抑制するために readOnly
プロパティを追加します。
// ✅ Good: readonly controlled input without on change
<input value={something} readOnly={true} />
チェックボックスをクリックしても更新されない
チェックボックスを checked
だけでレンダーし、onChange
が指定されていない場合、コンソールにエラーが表示されます。
// 🔴 Bug: controlled checkbox with no onChange handler
<input type="checkbox" checked={something} />
checked
prop to a form field without an onChange
handler. This will render a read-only field. If the field should be mutable use defaultChecked
. Otherwise, set either onChange
or readOnly
.エラーメッセージが示すように、もし単に初期値を指定 したかった場合は、代わりに defaultChecked
を渡します。
// ✅ Good: uncontrolled checkbox with an initial value
<input type="checkbox" defaultChecked={something} />
状態変数を使用してこのチェックボックスを制御したい場合は、onChange
ハンドラを指定します。
// ✅ Good: controlled checkbox with onChange
<input type="checkbox" checked={something} onChange={e => setSomething(e.target.checked)} />
チェックボックスが意図的に読み取り専用である場合は、エラーを抑制するために readOnly
プロパティを追加します。
// ✅ Good: readonly controlled input without on change
<input type="checkbox" checked={something} readOnly={true} />
入力カーソルがキーストロークごとに先頭にジャンプしてしまう
入力を制御する場合は、onChange
を使用して、DOM からの状態変数を入力の値に更新する必要があります。
e.target.value
(チェックボックスの場合は e.target.checked
) 以外のものに更新することはできません。
function handleChange(e) {
// 🔴 Bug: updating an input to something other than e.target.value
setFirstName(e.target.value.toUpperCase());
}
非同期的に更新することもできません。
function handleChange(e) {
// 🔴 Bug: updating an input asynchronously
setTimeout(() => {
setFirstName(e.target.value);
}, 100);
}
コードを修正するには、それを e.target.value
に同期的に更新します。
function handleChange(e) {
// ✅ Updating a controlled input to e.target.value synchronously
setFirstName(e.target.value);
}
これで問題が解決しない場合は、キーストロークごとに入力が DOM から削除され、再追加されている可能性があります。これは、再レンダーするたびに誤って状態をリセットしてしまっている場合に発生することがあります。例えば、入力またはその親の 1 つが常に異なる key
属性を受け取っている場合や、またはコンポーネント関数の定義をネストしている場合(この場合はサポートされておらず、「内部」コンポーネントが常に別のツリーとみなされます)などが挙げられます。
“A component is changing an uncontrolled input to be controlled” というエラーが表示される
コンポーネントに value
を指定した場合、その value
は存続期間を通じて常に文字列である必要があります。
React はコンポーネントを非制御にするか制御するかを認識できないため、最初に value={unknown}
を渡し、後で value="some string"
を渡すことはできません。制御されるコンポーネントは、null
または unknown
ではなく、常に文字列 value
を受け取る必要があります。
もし value
が API や状態変数から取得される場合、初期値が null
や undefined
になる可能性があります。その場合は、初期値として空の文字列(''
)を設定するか、value={someValue ?? ''}
のようにして、value
が文字列であることを確実にしてください。
同様に、チェックボックスに checked
を渡す場合は、それが常にブール値であることを確認してください。