表单处理
在 React 中,表单处理通常分为“受控组件”和“非受控组件”。
1. 受控组件 (Recommended)
在受控组件中,表单数据由 React 组件的 state 处理。
实时编辑器
function ControlledForm() { const [name, setName] = useState(""); const [message, setMessage] = useState(""); const handleSubmit = (e) => { e.preventDefault(); alert(`提交内容 - 名字: ${name}, 留言: ${message}`); }; return ( <form onSubmit={handleSubmit} style={{ display: 'flex', flexDirection: 'column', gap: '10px' }}> <label> 姓名: <input value={name} onChange={e => setName(e.target.value)} /> </label> <label> 留言: <textarea value={message} onChange={e => setMessage(e.target.value)} /> </label> <button type="submit" style={{ padding: '8px', background: '#2563eb', color: 'white', border: 'none', borderRadius: '4px' }}> 提交 </button> <p style={{ color: '#666', fontSize: '14px' }}>实时预览: {name || "(未填写)"} - {message || "(未填写)"}</p> </form> ); }
结果
Loading...
2. 非受控组件 (Uncontrolled)
表单数据由 DOM 节点本身处理。使用 useRef 来从 DOM 节点中获取表单值。通常用于简单的、性能要求极高或是与第三方非 React 库集成的场景。
实时编辑器
function UncontrolledForm() { const inputRef = useRef(null); const handleSubmit = (e) => { e.preventDefault(); alert(`直接从 DOM 获取的值: ${inputRef.current.value}`); }; return ( <form onSubmit={handleSubmit}> <input type="text" ref={inputRef} placeholder="没绑定 state 的输入框" style={{ padding: '8px', borderRadius: '4px', border: '1px solid #ccc' }} /> <button type="submit" style={{ marginLeft: '10px', padding: '8px 16px' }}>获取值</button> </form> ); }
结果
Loading...
3. 常见表单控件
复选框与单选框
实时编辑器
function SelectionDemo() { const [isReady, setIsReady] = useState(false); const [fruit, setFruit] = useState("apple"); return ( <div style={{ padding: '15px', border: '1px dashed #2563eb', borderRadius: '8px' }}> <label style={{ display: 'block', marginBottom: '10px' }}> <input type="checkbox" checked={isReady} onChange={e => setIsReady(e.target.checked)} /> 准备好了吗? {isReady ? "✅ 已就绪" : "❌ 未就绪"} </label> <label> 选择喜欢的水果: <select value={fruit} onChange={e => setFruit(e.target.value)} style={{ marginLeft: '10px', padding: '4px' }}> <option value="apple">🍎 苹果</option> <option value="banana">🍌 香蕉</option> <option value="orange">🍊 橙子</option> </select> </label> <div style={{ marginTop: '10px', color: '#6366f1', fontWeight: 'bold' }}> 当前选择: {fruit} </div> </div> ); }
结果
Loading...
4. React 19 & Actions
React 19 引入了 Action 的概念,允许在 <form> 的 action 属性中直接传入同步或异步函数。React 会自动处理 pending 状态。
// React 19 示例 (需 React 19 环境)
function MyForm() {
const [error, submitAction, isPending] = useActionState(async (previousState, formData) => {
const name = formData.get("name");
try {
await updateName(name);
return null;
} catch (e) {
return e.message;
}
}, null);
return (
<form action={submitAction}>
<input name="name" />
<button type="submit" disabled={isPending}>
{isPending ? "提交中..." : "提交"}
</button>
{error && <p style={{ color: 'red' }}>{error}</p>}
</form>
);
}
小结
- 受控组件:数据双向绑定,React 拥有绝对控制权(官方推荐)。
- 非受控组件:通过
ref直接操作 DOM,减少渲染次数,适合极简场景。 - React 19 Actions:极大简化了异步提交逻辑,自动管理 Pending 和错误反馈。