在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。