這是一本書的一個章節,有關 react form 中的受控組件和非受控組件,感謝做者。html
原文連接:goshakkk.name/controlled-…前端
到底應該怎樣建立 form 呢?node
畢竟,form 是不少 web 應用程序的核心,而在 React 中處理 form 彷佛有一點基礎。react
不要怕,讓我來想你展現這些方法的不一樣,以及你應該選擇哪種。web
非受控輸入框就像傳統的 HTML 輸入框同樣:redux
class Form extends Component {
render() {
return (
<div> <input type="text" /> </div> ); } } 複製代碼
它們記錄了你輸入的信息,你可使用 ref 獲取它們的值。例如,在按鈕的 onClick 處理中:canvas
class Form extends Component {
handleSubmitClick = () => {
const name = this._name.value;
// do something with `name`
}
render() {
return (
<div> <input type="text" ref={input => this._name = input} /> <button onClick={this.handleSubmitClick}>Sign up</button> </div> ); } } 複製代碼
換句話說,當你須要的時候你須要從表單域中「拉」表單值。當表單提交時這種狀況會發生。微信
這是最簡單的實現表單輸入的方式,確定會有這樣使用的有效案例:在現實中處理簡單的表單,還有學習 react 的時候。前端工程師
然而他不夠強大,因此咱們看一下接下來這些受控的輸入框。dom
一個受控輸入框接收它的當前值做爲一個屬性,而且有一個回調來修改它的值。你能夠說這是處理這件事的一種更「 React 的方式」(不表明你老是要使用這種方式)。
<input value={someValue} onChange={handleChange} />
複製代碼
這是很好的……可是這個輸入框的值必需要存在於某處的state
中。一般,渲染輸入框的組件(即表單組件)把它保存在它的state
中:
class Form extends Component {
constructor() {
super();
this.state = {
name: '',
};
}
handleNameChange = (event) => {
this.setState({ name: event.target.value });
};
render() {
return (
<div> <input type="text" value={this.state.name} onChange={this.handleNameChange} /> </div> ); } } 複製代碼
(固然,它能夠保存在另外一個組件的狀態中,甚至是獨立的狀態存儲,例如 Redux )
每次你輸入一個新的字符,handleNameChange
被調用,他接收輸入的新值並把它設置到 state 中。
''
。a
而且handleNameChange
獲取了一個a
並調用setState
。輸入框接着從新渲染爲擁有一個 value 爲a
。b
,handleNameChange
獲取到值ab
並設置到 state 中,輸入框再次從新渲染,如今帶有屬性value="ab"
。這種流程把值的變化「推」給表單組件,所以Form
組件始終擁有輸入框的當前值,不須要明確地去要值。
這意味着你的數據( state )和 UI(輸入框)老是同步的,state 提供值給輸入框,輸入框請求Form
修改當前值。
這也意味着表單組件可以馬上響應輸入框變化,例如:
可是若是你不須要這些而且認爲非受控的會更簡單,那就去吧。
固然,有其餘的表單元素:複選框、單選框、下拉框、文本域。
若是經過一個 prop 來設置一個表單元素的 value ,它變爲「受控的」,就這樣。
每個表單元素有不一樣的用來設置 value 的 prop ,下面是一個總結的小表格
Element | Value property | Change callback | New value in the callback |
---|---|---|---|
<input type="text" /> |
value="string" | onChange | event.target.value |
<input type="checkbox" /> |
checked={boolean} | onChange | event.target.checked |
<input type="radio" /> |
checked={boolean} | onChange | event.target.checked |
<textarea /> |
value="string" | onChange | event.target.value |
<select /> |
value="option value" | onChange | event.target.value |
受控和非受控表單字段都有它們的價值,評估具體的場景來選擇方法——對你有用的就足夠了。
若是你的表單在 UI 反饋方面特別簡單,非受控的使用 refs 徹底能夠,你沒必要聽各類文章說「很差」。
特性 | 非受控的 | 受控的 |
---|---|---|
一次性取值(如:提交時) | true | true |
提交時校驗 | true | true |
實時表單域校驗 | false | true |
按條件禁用提交按鈕 | false | true |
強制輸入格式 | false | true |
多輸入框控制單個數據 | false | true |
動態輸入框 | false | true |
並且,這不是一種一勞永逸的決定:你老是能夠遷移到受控輸入框。從非受控輸入遷移到受控輸入並不困難。
最後,這是個人有關React中表單的文章的組織清單。
關於譯者:第一次翻譯文章,英語水平不好,表述不夠優雅,有問題歡迎指正。
本文首發於掘金社區,轉載請知悉本人,防止竊取附上我的小站,後續文章會同步。
最後發一條小廣告,字節跳動招各類級別前端工程師,從 HTML五、 CSS三、Typescript、React、canvas、node 到 WebRTC、WebAssembly、WebGL,以及C++、Electron 等等,各類有趣的事情。聯繫微信 / QQ 1091381572 備註掘金,發簡歷給我,歡迎投遞。