/

在React中處理表單

在React中處理表單

如何在React應用程序中處理表單

表單是少數默認具有互動性的HTML元素之一。

它們的設計目的是允許用戶與頁面進行互動。

常見的表單用途?

  • 搜索
  • 聯繫表單
  • 購物車結帳
  • 登錄和註冊
  • 等等!

使用React可以使我們的表單具有更多互動性且不那麼靜態。

在React中處理表單有兩種主要方式,它們在基本級別上有所不同:數據是如何管理的。

  • 如果數據由DOM處理,我們稱之為非受控組件
  • 如果數據由組件處理,我們稱之為受控組件

如您所想,大多數情況下都會使用受控組件。組件狀態是唯一的真相來源,而不是DOM。但有時候,當使用一些具有固有行為的表單字段時,您被迫使用不受控制的組件,例如<input type="file">字段。

當表單字段中的元素狀態更改時,我們使用onChange屬性來跟踪它。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
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無法在該方法內部訪問:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
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方法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
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可以讓所有的事情變得簡單得多:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
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的用法:

1
<textarea value={this.state.address} onChange={this.handleChange} />

對於select標籤也是一樣:

1
2
3
4
<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()定義的屬性來獲取對該字段的引用,並在提交處理程序中使用它來獲取其值:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
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