如何在React應用程序中處理表單
表單是少數默認具有互動性的HTML元素之一。
它們的設計目的是允許用戶與頁面進行互動。
常見的表單用途?
- 搜索
- 聯繫表單
- 購物車結帳
- 登錄和註冊
- 等等!
使用React可以使我們的表單具有更多互動性且不那麼靜態。
在React中處理表單有兩種主要方式,它們在基本級別上有所不同:數據是如何管理的。
- 如果數據由DOM處理,我們稱之為非受控組件
- 如果數據由組件處理,我們稱之為受控組件
如您所想,大多數情況下都會使用受控組件。組件狀態是唯一的真相來源,而不是DOM。但有時候,當使用一些具有固有行為的表單字段時,您被迫使用不受控制的組件,例如<input type="file">
字段。
當表單字段中的元素狀態更改時,我們使用onChange
屬性來跟踪它。
class Form extends React.Component {
constructor(props) {
super(props)
this.state = { username: '' }
}
handleChange(event) {}
render() {
return (
<form>
Username:
<input
type="text"
value={this.state.username}
onChange={this.handleChange}
/>
</form>
)
}
}
在類組件中,為了設置新的狀態,我們必須將this
綁定到handleChange
方法,否則this
無法在該方法內部訪問:
class Form extends React.Component {
constructor(props) {
super(props)
this.state = { username: '' }
this.handleChange = this.handleChange.bind(this)
}
handleChange(event) {
this.setState({ username: event.target.value })
}
render() {
return (
<form>
<input
type="text"
value={this.state.username}
onChange={this.handleChange}
/>
</form>
)
}
}
同樣地,當表單提交時,我們使用表單上的onSubmit
屬性來調用handleSubmit
方法:
class Form extends React.Component {
constructor(props) {
super(props)
this.state = { username: '' }
this.handleChange = this.handleChange.bind(this)
this.handleSubmit = this.handleSubmit.bind(this)
}
handleChange(event) {
this.setState({ username: event.target.value })
}
handleSubmit(event) {
alert(this.state.username)
event.preventDefault()
}
render() {
return (
<form onSubmit={this.handleSubmit}>
<input
type="text"
value={this.state.username}
onChange={this.handleChange}
/>
<input type="submit" value="Submit" />
</form>
)
}
}
使用hooks可以讓所有的事情變得簡單得多:
const Form = props => {
const [username, setUsername] = useState()
const handleChangeUsername = e => {
setUsername(e.target.value)
}
const handleSubmit = event => {
alert(username)
event.preventDefault()
}
render() {
return (
<form onSubmit={handleSubmit}>
Username:
<input
type="text"
value={username}
onChange={handleChangeUsername}
/>
</form>
)
}
}
表單中的驗證可以在handleChange
方法中處理:您可以訪問狀態的舊值和新值。您可以檢查新值,如果不合法,則拒絕更新的值(並以某種方式向用戶通知)。
HTML表單是不一致的。它們有很長的歷史,其表現出來。然而,React使事情對我們來說更一致,您可以使用其value
屬性來獲取(和更新)字段。
例如,這是textarea
的用法:
<textarea value={this.state.address} onChange={this.handleChange} />
對於select
標籤也是一樣:
<select value="{this.state.age}" onChange="{this.handleChange}">
<option value="teen">少於18歲</option>
<option value="adult">18+</option>
</select>
之前我們提到了<input type="file">
字段。它的使用方式略有不同。
在這種情況下,您需要通過將ref
屬性分配給構造函數中使用React.createRef()
定義的屬性來獲取對該字段的引用,並在提交處理程序中使用它來獲取其值:
class FileInput extends React.Component {
constructor(props) {
super(props)
this.curriculum = React.createRef()
this.handleSubmit = this.handleSubmit.bind(this)
}
handleSubmit(event) {
alert(this.curriculum.current.files[0].name)
event.preventDefault()
}
render() {
return (
<form onSubmit={this.handleSubmit}>
<input type="file" ref={this.curriculum} />
<input type="submit" value="Submit" />
</form>
)
}
}
這是非受控狀態組件的方式。狀態存儲在DOM中,而不是組件狀態中(請注意我們使用了this.curriculum
來訪問上傳的文件,並且尚未觸及state
)。
我知道您在想什麼-除了這些基礎知識外,肯定有一個簡化所有此表單處理的庫,可以自動執行驗證、錯誤處理等操作,對吧?當然有一個很棒的庫,它就是Formik。