内置浏览器 <input>
组件 可让你渲染不同类型的表单输入。
¥The built-in browser <input>
component lets you render different kinds of form inputs.
<input />
参考
¥Reference
<input>
要显示输入,请渲染 内置浏览器 <input>
组件。
¥To display an input, render the built-in browser <input>
component.
<input name="myInput" />
属性
¥Props
<input>
支持所有 普通元素属性。
¥<input>
supports all common element props.
formAction
:字符串或函数。为 type="submit"
和 type="image"
覆盖父 <form action>
。当 URL 传递到 action
时,表单的行为将类似于标准 HTML 表单。当函数传递给 formAction
时,该函数将处理表单提交。参见 <form action>
。
¥formAction
: A string or function. Overrides the parent <form action>
for type="submit"
and type="image"
. When a URL is passed to action
the form will behave like a standard HTML form. When a function is passed to formAction
the function will handle the form submission. See <form action>
.
你可以通过传递以下属性之一来 控制输入:
¥You can make an input controlled by passing one of these props:
-
checked
:一个布尔值。对于复选框输入或单选按钮,控制它是否被选中。¥
checked
: A boolean. For a checkbox input or a radio button, controls whether it is selected. -
value
:一个字符串。对于文本输入,控制其文本。(对于单选按钮,指定其表单数据。)¥
value
: A string. For a text input, controls its text. (For a radio button, specifies its form data.)
当你传递它们中的任何一个时,你还必须传递一个 onChange
处理程序来更新传递的值。
¥When you pass either of them, you must also pass an onChange
handler that updates the passed value.
这些 <input>
属性仅与不受控制的输入相关:
¥These <input>
props are only relevant for uncontrolled inputs:
-
defaultChecked
:一个布尔值。为type="checkbox"
和type="radio"
输入指定 初始值。¥
defaultChecked
: A boolean. Specifies the initial value fortype="checkbox"
andtype="radio"
inputs. -
defaultValue
:一个字符串。为文本输入指定 初始值。¥
defaultValue
: A string. Specifies the initial value for a text input.
这些 <input>
属性与非受控和受控输入相关:
¥These <input>
props are relevant both for uncontrolled and controlled inputs:
-
accept
:一个字符串。指定type="file"
输入接受哪些文件类型。¥
accept
: A string. Specifies which filetypes are accepted by atype="file"
input. -
alt
:一个字符串。指定type="image"
输入的替代图片文本。¥
alt
: A string. Specifies the alternative image text for atype="image"
input. -
capture
:一个字符串。指定type="file"
输入捕获的媒体(麦克风、视频或摄像头)。¥
capture
: A string. Specifies the media (microphone, video, or camera) captured by atype="file"
input. -
autoComplete
:一个字符串。指定可能的 自动补齐行为。 之一¥
autoComplete
: A string. Specifies one of the possible autocomplete behaviors. -
autoFocus
:一个布尔值。如果是true
,React 会将元素集中在挂载上。¥
autoFocus
: A boolean. Iftrue
, React will focus the element on mount. -
dirname
:一个字符串。指定元素方向性的表单字段名称。¥
dirname
: A string. Specifies the form field name for the element’s directionality. -
disabled
:一个布尔值。如果是true
,输入将不会是交互式的,并且会显示为灰色。¥
disabled
: A boolean. Iftrue
, the input will not be interactive and will appear dimmed. -
children
:<input>
不接受子级。¥
children
:<input>
does not accept children. -
form
:一个字符串。指定此输入所属的<form>
的id
。如果省略,它是最接近的父表单。¥
form
: A string. Specifies theid
of the<form>
this input belongs to. If omitted, it’s the closest parent form. -
formAction
:一个字符串。为type="submit"
和type="image"
覆盖父<form action>
。¥
formAction
: A string. Overrides the parent<form action>
fortype="submit"
andtype="image"
. -
formEnctype
:一个字符串。为type="submit"
和type="image"
覆盖父<form enctype>
。¥
formEnctype
: A string. Overrides the parent<form enctype>
fortype="submit"
andtype="image"
. -
formMethod
:一个字符串。为type="submit"
和type="image"
覆盖父<form method>
。¥
formMethod
: A string. Overrides the parent<form method>
fortype="submit"
andtype="image"
. -
formNoValidate
:一个字符串。为type="submit"
和type="image"
覆盖父<form noValidate>
。¥
formNoValidate
: A string. Overrides the parent<form noValidate>
fortype="submit"
andtype="image"
. -
formTarget
:一个字符串。为type="submit"
和type="image"
覆盖父<form target>
。¥
formTarget
: A string. Overrides the parent<form target>
fortype="submit"
andtype="image"
. -
height
:一个字符串。指定type="image"
的图片高度。¥
height
: A string. Specifies the image height fortype="image"
. -
list
:一个字符串。使用自动补齐选项指定<datalist>
的id
。¥
list
: A string. Specifies theid
of the<datalist>
with the autocomplete options. -
max
:一个号码。指定数字和日期时间输入的最大值。¥
max
: A number. Specifies the maximum value of numerical and datetime inputs. -
maxLength
:一个号码。指定文本和其他输入的最大长度。¥
maxLength
: A number. Specifies the maximum length of text and other inputs. -
min
:一个号码。指定数字和日期时间输入的最小值。¥
min
: A number. Specifies the minimum value of numerical and datetime inputs. -
minLength
:一个号码。指定文本和其他输入的最小长度。¥
minLength
: A number. Specifies the minimum length of text and other inputs. -
multiple
:一个布尔值。指定<type="file"
和type="email"
是否允许多个值。¥
multiple
: A boolean. Specifies whether multiple values are allowed for<type="file"
andtype="email"
. -
¥
name
: A string. Specifies the name for this input that’s submitted with the form. -
onChange
:一个Event
处理程序 函数。受控输入。 需要 当输入的值被用户更改时立即触发(例如,它在每次击键时触发)。行为类似于浏览器input
事件。¥
onChange
: AnEvent
handler function. Required for controlled inputs. Fires immediately when the input’s value is changed by the user (for example, it fires on every keystroke). Behaves like the browserinput
event. -
onChangeCapture
:在 捕获阶段。 中触发的onChange
版本¥
onChangeCapture
: A version ofonChange
that fires in the capture phase. -
onInput
:一个Event
处理程序 函数。当用户更改值时立即触发。由于历史原因,在 React 中惯用的是使用onChange
,它的工作方式类似。¥
onInput
: AnEvent
handler function. Fires immediately when the value is changed by the user. For historical reasons, in React it is idiomatic to useonChange
instead which works similarly. -
onInputCapture
:在 捕获阶段。 中触发的onInput
版本¥
onInputCapture
: A version ofonInput
that fires in the capture phase. -
onInvalid
:一个Event
处理程序 函数。如果输入在表单提交时验证失败,则触发。与内置的invalid
事件不同,ReactonInvalid
事件冒泡。¥
onInvalid
: AnEvent
handler function. Fires if an input fails validation on form submit. Unlike the built-ininvalid
event, the ReactonInvalid
event bubbles. -
onInvalidCapture
:在 捕获阶段。 中触发的onInvalid
版本¥
onInvalidCapture
: A version ofonInvalid
that fires in the capture phase. -
onSelect
:一个Event
处理程序 函数。在<input>
内的选择更改后触发。React 扩展了onSelect
事件以在空选择和编辑时触发(这可能会影响选择)。¥
onSelect
: AnEvent
handler function. Fires after the selection inside the<input>
changes. React extends theonSelect
event to also fire for empty selection and on edits (which may affect the selection). -
onSelectCapture
:在 捕获阶段。 中触发的onSelect
版本¥
onSelectCapture
: A version ofonSelect
that fires in the capture phase. -
pattern
:一个字符串。指定value
必须匹配的模式。¥
pattern
: A string. Specifies the pattern that thevalue
must match. -
placeholder
:一个字符串。输入值为空时以暗色显示。¥
placeholder
: A string. Displayed in a dimmed color when the input value is empty. -
readOnly
:一个布尔值。如果为true
,则用户无法编辑输入。¥
readOnly
: A boolean. Iftrue
, the input is not editable by the user. -
required
:一个布尔值。如果是true
,则必须提供该值以便提交表单。¥
required
: A boolean. Iftrue
, the value must be provided for the form to submit. -
size
:一个号码。类似于设置宽度,但单位取决于控件。¥
size
: A number. Similar to setting width, but the unit depends on the control. -
src
:一个字符串。指定type="image"
输入的图片源。¥
src
: A string. Specifies the image source for atype="image"
input. -
step
:正数或'any'
字符串。指定有效值之间的距离。¥
step
: A positive number or an'any'
string. Specifies the distance between valid values. -
¥
type
: A string. One of the input types. -
width
:一个字符串。指定type="image"
输入的图片宽度。¥
width
: A string. Specifies the image width for atype="image"
input.
注意事项
¥Caveats
-
复选框需要
checked
(或defaultChecked
),而不是value
(或defaultValue
)。¥Checkboxes need
checked
(ordefaultChecked
), notvalue
(ordefaultValue
). -
如果文本输入接收到字符串
value
属性,它将是 作为控制处理。¥If a text input receives a string
value
prop, it will be treated as controlled. -
如果复选框或单选按钮收到布尔值
checked
属性,它将是 作为控制处理。¥If a checkbox or a radio button receives a boolean
checked
prop, it will be treated as controlled. -
输入不能同时受控和不受控。
¥An input can’t be both controlled and uncontrolled at the same time.
-
输入在其生命周期内无法在受控或不受控之间切换。
¥An input cannot switch between being controlled or uncontrolled over its lifetime.
-
每个受控输入都需要一个
onChange
事件处理程序来同步更新其支持值。¥Every controlled input needs an
onChange
event handler that synchronously updates its backing value.
用法
¥Usage
显示不同类型的输入
¥Displaying inputs of different types
要显示输入,请渲染 <input>
组件。默认情况下,它将是文本输入。你可以传递 type="checkbox"
复选框,type="radio"
单选按钮,或其他输入类型之一。
¥To display an input, render an <input>
component. By default, it will be a text input. You can pass type="checkbox"
for a checkbox, type="radio"
for a radio button, or one of the other input types.
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> </> ); }
为输入提供标签
¥Providing a label for an input
通常,你会将每个 <input>
放在 <label>
标签中。这告诉浏览器这个标签与那个输入相关联。当用户点击标签时,浏览器会自动聚焦输入。它对于可访问性也很重要:当用户聚焦相关输入时,屏幕阅读器将宣布标签标题。
¥Typically, you will place every <input>
inside a <label>
tag. This tells the browser that this label is associated with that input. When the user clicks the label, the browser will automatically focus the input. It’s also essential for accessibility: a screen reader will announce the label caption when the user focuses the associated input.
如果不能将 <input>
嵌套到 <label>
中,通过将相同的 ID 传递给 <input id>
和 <label htmlFor>
。 来关联它们 为了避免一个组件的多个实例之间的冲突,使用 useId
。 生成这样的 ID
¥If you can’t nest <input>
into a <label>
, associate them by passing the same ID to <input id>
and <label htmlFor>
. To avoid conflicts between multiple instances of one component, generate such an ID with useId
.
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" /> </> ); }
为输入提供初始值
¥Providing an initial value for an input
你可以选择为任何输入指定初始值。将其作为文本输入的 defaultValue
字符串传递。复选框和单选按钮应使用 defaultChecked
布尔值指定初始值。
¥You can optionally specify the initial value for any input. Pass it as the defaultValue
string for text inputs. Checkboxes and radio buttons should specify the initial value with the defaultChecked
boolean instead.
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> </> ); }
提交表单时读取输入值
¥Reading the input values when submitting a form
在你的输入周围添加一个 <form>
,里面有一个 <button type="submit">
。它将调用你的 <form onSubmit>
事件处理程序。默认情况下,浏览器会将表单数据发送到当前 URL 并刷新页面。你可以通过调用 e.preventDefault()
来覆盖该行为。使用 new FormData(e.target)
读取表单数据。
¥Add a <form>
around your inputs with a <button type="submit">
inside. It will call your <form onSubmit>
event handler. By default, the browser will send the form data to the current URL and refresh the page. You can override that behavior by calling e.preventDefault()
. Read the form data with 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> ); }
使用状态变量控制输入
¥Controlling an input with a state variable
像 <input />
这样的输入是不受控制的。即使你 传递初始值 喜欢 <input defaultValue="Initial text" />
,你的 JSX 也只是指定了初始值。它不控制现在应该是什么值。
¥An input like <input />
is uncontrolled. Even if you pass an initial value like <input defaultValue="Initial text" />
, your JSX only specifies the initial value. It does not control what the value should be right now.
要渲染受控输入,请将 value
属性传递给它(或 checked
用于复选框和单选框)。React 将强制输入始终包含你传递的 value
。通常,你会通过声明一个 状态变量 来做到这一点
¥To render a controlled input, pass the value
prop to it (or checked
for checkboxes and radios). React will force the input to always have the value
you passed. Usually, you would do this by declaring a state variable:
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:
¥A controlled input makes sense if you needed state anyway—for example, to re-render your UI on every edit:
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>}
...
如果你想提供多种方式来调整输入状态(例如,通过单击按钮),它也很有用:
¥It’s also useful if you want to offer multiple ways to adjust the input state (for example, by clicking a button):
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
字段),请将你的状态变量初始化为空字符串 (''
)。
¥The value
you pass to controlled components should not be undefined
or null
. If you need the initial value to be empty (such as with the firstName
field below), initialize your state variable to an empty string (''
).
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> } </> ); }
优化每次击键时的重新渲染
¥Optimizing re-rendering on every keystroke
当你使用受控输入时,你可以设置每次击键的状态。如果包含你的状态的组件重新渲染一棵大树,这可能会变慢。有几种方法可以优化重新渲染性能。
¥When you use a controlled input, you set the state on every keystroke. If the component containing your state re-renders a large tree, this can get slow. There’s a few ways you can optimize re-rendering performance.
例如,假设你从一个在每次击键时重新渲染所有页面内容的表单开始:
¥For example, suppose you start with a form that re-renders all page content on every keystroke:
function App() {
const [firstName, setFirstName] = useState('');
return (
<>
<form>
<input value={firstName} onChange={e => setFirstName(e.target.value)} />
</form>
<PageContent />
</>
);
}
由于 <PageContent />
不依赖于输入状态,你可以将输入状态移动到它自己的组件中:
¥Since <PageContent />
doesn’t rely on the input state, you can move the input state into its own component:
function App() {
return (
<>
<SignupForm />
<PageContent />
</>
);
}
function SignupForm() {
const [firstName, setFirstName] = useState('');
return (
<form>
<input value={firstName} onChange={e => setFirstName(e.target.value)} />
</form>
);
}
这显着提高了性能,因为现在只有 SignupForm
在每次击键时重新渲染。
¥This significantly improves performance because now only SignupForm
re-renders on every keystroke.
如果无法避免重新渲染(例如,如果 PageContent
取决于搜索输入的值),则 useDeferredValue
可以让你保持受控输入响应,即使在大型重新渲染的过程中也是如此。
¥If there is no way to avoid re-rendering (for example, if PageContent
depends on the search input’s value), useDeferredValue
lets you keep the controlled input responsive even in the middle of a large re-render.
故障排除
¥Troubleshooting
当我输入时,我的文本输入没有更新
¥My text input doesn’t update when I type into it
如果你使用 value
而没有 onChange
渲染输入,你将在控制台中看到错误:
¥If you render an input with value
but no onChange
, you will see an error in the console:
// 🔴 Bug: controlled text input with no onChange handler
<input value={something} />
如错误消息所示,如果你只想 指定初始值, 传递 defaultValue
:
¥As the error message suggests, if you only wanted to specify the initial value, pass defaultValue
instead:
// ✅ Good: uncontrolled input with an initial value
<input defaultValue={something} />
如果你想要 用状态变量控制这个输入, 指定一个 onChange
处理程序:
¥If you want to control this input with a state variable, specify an onChange
handler:
// ✅ Good: controlled input with onChange
<input value={something} onChange={e => setSomething(e.target.value)} />
如果该值是有意只读的,请添加 readOnly
属性以抑制错误:
¥If the value is intentionally read-only, add a readOnly
prop to suppress the error:
// ✅ Good: readonly controlled input without on change
<input value={something} readOnly={true} />
当我点击它时,我的复选框没有更新
¥My checkbox doesn’t update when I click on it
如果你渲染一个带有 checked
但没有 onChange
的复选框,你将在控制台中看到一个错误:
¥If you render a checkbox with checked
but no onChange
, you will see an error in the console:
// 🔴 Bug: controlled checkbox with no onChange handler
<input type="checkbox" checked={something} />
如错误消息所示,如果你只想 指定初始值, 传递 defaultChecked
:
¥As the error message suggests, if you only wanted to specify the initial value, pass defaultChecked
instead:
// ✅ Good: uncontrolled checkbox with an initial value
<input type="checkbox" defaultChecked={something} />
如果你想要 使用状态变量控制此复选框, 指定一个 onChange
处理程序:
¥If you want to control this checkbox with a state variable, specify an onChange
handler:
// ✅ Good: controlled checkbox with onChange
<input type="checkbox" checked={something} onChange={e => setSomething(e.target.checked)} />
如果复选框是有意只读的,请添加 readOnly
属性以抑制错误:
¥If the checkbox is intentionally read-only, add a readOnly
prop to suppress the error:
// ✅ Good: readonly controlled input without on change
<input type="checkbox" checked={something} readOnly={true} />
我的输入插入符号在每次击键时跳转到开头
¥My input caret jumps to the beginning on every keystroke
如果你 控制输入,,则必须在 onChange
期间将其状态变量更新为来自 DOM 的输入值。
¥If you control an input, you must update its state variable to the input’s value from the DOM during onChange
.
你不能将其更新为 e.target.value
(或 e.target.checked
用于复选框)以外的内容:
¥You can’t update it to something other than e.target.value
(or e.target.checked
for checkboxes):
function handleChange(e) {
// 🔴 Bug: updating an input to something other than e.target.value
setFirstName(e.target.value.toUpperCase());
}
你也不能异步更新它:
¥You also can’t update it asynchronously:
function handleChange(e) {
// 🔴 Bug: updating an input asynchronously
setTimeout(() => {
setFirstName(e.target.value);
}, 100);
}
要修复你的代码,请将其同步更新到 e.target.value
:
¥To fix your code, update it synchronously to e.target.value
:
function handleChange(e) {
// ✅ Updating a controlled input to e.target.value synchronously
setFirstName(e.target.value);
}
如果这不能解决问题,则输入可能会在每次击键时从 DOM 中删除并重新添加。如果你在每次重新渲染时不小心 重置状态,就会发生这种情况,例如,如果输入或其父项之一总是接收到不同的 key
属性,或者如果你嵌套组件函数定义(不支持并导致 “inner” 组件 总是被认为是不同的树)。
¥If this doesn’t fix the problem, it’s possible that the input gets removed and re-added from the DOM on every keystroke. This can happen if you’re accidentally resetting state on every re-render, for example if the input or one of its parents always receives a different key
attribute, or if you nest component function definitions (which is not supported and causes the “inner” component to always be considered a different tree).
我收到错误:“组件正在将不受控制的输入更改为受控”
¥I’m getting an error: “A component is changing an uncontrolled input to be controlled”
如果你向组件提供 value
,它必须在其整个生命周期中保持为字符串。
¥If you provide a value
to the component, it must remain a string throughout its lifetime.
你不能先传 value={undefined}
再传 value="some string"
,因为 React 不知道你是想让组件不受控制还是受控。受控组件应始终接收字符串 value
,而不是 null
或 undefined
。
¥You cannot pass value={undefined}
first and later pass value="some string"
because React won’t know whether you want the component to be uncontrolled or controlled. A controlled component should always receive a string value
, not null
or undefined
.
如果你的 value
来自 API 或状态变量,它可能会被初始化为 null
或 undefined
。在这种情况下,要么最初将其设置为空字符串 (''
),要么传递 value={someValue ?? ''}
以确保 value
是一个字符串。
¥If your value
is coming from an API or a state variable, it might be initialized to null
or undefined
. In that case, either set it to an empty string (''
) initially, or pass value={someValue ?? ''}
to ensure value
is a string.
同样,如果将 checked
传递给复选框,请确保它始终为布尔值。
¥Similarly, if you pass checked
to a checkbox, ensure it’s always a boolean.