如何在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