表单是很常见的页面交互。React 里的“受控组件”听起来有些抽象,先从一个输入框开始:让输入框显示的值始终来自组件状态。
让状态成为数据来源
在受控输入框里,value 由 state 提供,每次输入时再通过 onChange 更新 state。这样页面显示的内容和 React 保存的值保持一致。
import { useState } from 'react'
export function NameField() {
const [name, setName] = useState('')
return (
<label>
昵称
<input
value={name}
onChange={(event) => setName(event.target.value)}
/>
</label>
)
}
处理表单提交
表单提交时可以读取当前 state。preventDefault() 用来阻止浏览器默认刷新行为,之后再把数据交给页面自己的处理函数。
function handleSubmit(event: React.FormEvent<HTMLFormElement>) {
event.preventDefault()
console.log(name)
}
真实项目里,提交前还需要做必填校验,并在提交期间给用户明确反馈。
容易遇到的小问题
- 给输入框设置了
value,却没有onChange,输入框会变成只读。 - 初始值可能是
undefined,之后又变成字符串。文本输入框最好从一开始就使用''。 - 表单里有多个字段时,可以分别管理状态;字段更多时再考虑统一的表单方案。
小结
受控输入框把数据流讲得很清楚:state 决定当前显示值,用户输入触发事件,事件再更新 state。理解这个循环后,表单校验和提交状态也更容易组织。