Skip to content

ReactJS - 表单

处理表单是 Web 开发的基本组成部分。React 提供了一种使用“受控组件”(Controlled Components)概念来管理表单数据的强大方式。本章将解释如何使用函数组件(functional components)和 Hooks 在现代 React 中创建和管理表单。

在 HTML 中,诸如 <input>、<textarea> 和 <select> 的表单元素通常维护自己的状态并根据用户输入进行更新。在 React 中,受控组件是指其表单数据由 React 组件的状态(state)处理的组件。React 状态成为“单一数据源”(single source of truth)。

这意味着:

  1. 输入元素的值由 React 状态驱动。

  2. 输入的任何更改(例如,用户输入)都会触发一个事件处理函数(event handler),该函数更新 React 状态。

让我们创建一个包含单个文本输入的简单表单。此输入的值将存储在组件的状态中,并且任何更改都将更新状态,从而重新渲染组件。

import React, { useState } from 'react';
function App() {
const [inputValue, setInputValue] = useState('Initial data...');
const handleChange = (event) => {
setInputValue(event.target.value);
};
return (
<div>
<input
type="text"
value={inputValue}
onChange={handleChange}
/>
<h4>Current Value: {inputValue}</h4>
</div>
);
}
export default App;
import React from 'react';
import ReactDOM from 'react-dom/client';
import App from './App.jsx';
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
<React.StrictMode>
<App />
</React.StrictMode>
);

在此示例中:

  • useState('Initial data...') 使用 ‘Initial data…’ 初始化我们的 inputValue 状态。

  • <input> 元素的 value prop 设置为 inputValue。这使其成为一个受控组件。

  • onChange prop 设置为 handleChange 函数。每当用户在输入字段中输入时,都会调用 handleChange。

  • handleChange 接收一个事件对象,event.target.value 包含输入的当前值。然后它调用 setInputValue 来更新状态。

  • <h4> 标签显示当前的 inputValue,表明状态是实时更新的。

当你在输入字段中输入时,下面显示的文本会立即更新。这就是受控组件的精髓。

带有子组件的表单(属性透传 - Prop Drilling)

Section titled “带有子组件的表单(属性透传 - Prop Drilling)”

有时,你可能在子组件中有表单输入或显示元素。你可以在父组件中管理状态,并将数据和更新函数作为 prop 传递下去。

import React, { useState } from 'react';
// Child component
function DataDisplayInput({ data, onDataChange }) {
return (
<div>
<input
type="text"
value={data}
onChange={onDataChange}
/>
<h3>Child Component Display: {data}</h3>
</div>
);
}
// Parent component
function App() {
const [appData, setAppData] = useState('Initial data...');
const handleAppDataChange = (event) => {
setAppData(event.target.value);
};
return (
<div>
<h2>Parent Component</h2>
<DataDisplayInput
data={appData}
onDataChange={handleAppDataChange}
/>
<h4>Parent Component Display: {appData}</h4>
</div>
);
}
export default App;

在这个更复杂的示例中:

  • App 组件(父组件)持有 appData 状态和 handleAppDataChange 函数。

  • 它渲染 DataDisplayInput 组件(子组件),将 appData 作为 data prop 传递,并将 handleAppDataChange 作为 onDataChange prop 传递。

  • DataDisplayInput 子组件使用这些 prop 来控制其输入字段并显示数据。

  • 当 DataDisplayInput 中的输入发生变化时,它会调用 this.props.onDataChange(即来自父组件的 handleAppDataChange),从而更新 App 组件中的状态。

这种模式被称为“状态提升”(lifting state up)。虽然对于简单情况很有效,但对于深度嵌套的组件或复杂的状态交互,请考虑使用 React 的 Context API 或状态管理库,如 Redux 或 Zustand。有关这些高级模式的更多详细信息,你可以搜索 ‘React Context API’ 或 ‘React state management libraries’。

受控组件的优势:

  • 单一数据源:状态在一个地方管理,使调试更容易。

  • 验证:可以在 onChange 处理函数中实时验证或转换输入。

  • 条件逻辑:根据状态轻松启用/禁用提交按钮或显示/隐藏表单元素。

记住类似地处理其他表单元素,如 <textarea>、<select>、复选框和单选按钮,通过控制它们的 value(或复选框/单选按钮的 checked)并使用 onChange 处理函数来更新状态。