一、受控組件html
在HTML當中,像<input>
,<textarea>
, 和 <select>
這類表單元素會維持自身狀態,並根據用戶輸入進行更新。但在React中,可變的狀態一般保存在組件的狀態屬性中,而且只能用 setState()
方法進行更新。react
咱們經過使react變成一種單一數據源的狀態來結合兩者。React負責渲染表單的組件仍然控制用戶後續輸入時所發生的變化。相應的,其值由React控制的輸入表單元素稱爲「受控組件」。segmentfault
因爲 value
屬性是在咱們的表單元素上設置的,所以顯示的值將始終爲 React數據源上this.state.value
的值。因爲每次按鍵都會觸發 handleChange
來更新當前React的state,所展現的值也會隨着不一樣用戶的輸入而更新。bash
<input type="text" value={this.state.value} onChange={this.handleChange} />複製代碼
二、非受控組件架構
要編寫一個非受控組件,而非爲每一個狀態更新編寫事件處理程序,你能夠 使用 ref 從 DOM 獲取表單值。
dom
在 React 的生命週期中,表單元素上的 value
屬性將會覆蓋 DOM 中的值。使用非受控組件時,一般你但願 React 能夠爲其指定初始值,但再也不控制後續更新。要解決這個問題,你能夠指定一個 defaultValue
屬性而不是 value
。
性能
<input type="text" defaultValue={'1232'} ref={this.input} />複製代碼
舉例:ui
class NameForm extends React.Component {
constructor(props) {
super(props);
this.handleSubmit = this.handleSubmit.bind(this);
this.handleChange = this.handleChange.bind(this);
this.input = React.createRef();
this.state = {
value:'567'
}
}
handleSubmit(event) {
alert('A name was submitted: ' + this.input.current.value);
event.preventDefault();
}
handleChange(e){
this.setState({value: e.target.value});
}
render() {
return (
<form onSubmit={this.handleSubmit}>
<label>
Name:
<input type="text" defaultValue={'1232'} ref={this.input} />
<input type="text" value={this.state.value} onChange={this.handleChange} />
</label>
<input type="submit" value="Submit" />
</form>
);
}
}
ReactDOM.render(
<NameForm />,
document.getElementById('root')
);複製代碼
在 CodePen 上嘗試。
this
三、對比受控組件和非受控組件spa
將輸入的字母轉化爲大寫展現
<input
type="text"
value={this.state.value}
onChange={(e) => {
this.setState({
value: e.target.value.toUpperCase(),
});
}}
/>複製代碼
直接展現輸入的字母
<input
type="text"
defaultValue={this.state.value}
/>複製代碼
a、性能上的問題
在受控組件中,每次表單的值發生變化,都會調用一次onChange事件處理器,這確實會帶來性能上的的損耗,雖然使用費受控組件不會出現這些問題,但仍然不提倡使用非受控組件,這個問題能夠經過Flux/Redux應用架構等方式來達到統一組件狀態的目的.
b、是否須要事件綁定
使用受控組件須要爲每個組件綁定一個change事件,而且定義一個事件處理器來同步表單值和組件的狀態,這是一個必要條件.固然,某些狀況可使用一個事件處理器來處理多個表單域
import React, { Component } from 'react';
class Controlled extends Component {
constructor(...args) {
super(...args);
this.state = {
name: 'xiaoming',
age: 18,
};
}
handleChange = (name, e) => {
const { value } = e.target;
this.setState({
[name]: value,
});
}
render() {
const { name, age } = this.state;
return (
<div>
<input type="text" value={name} onChange={this.handleChange.bind(this, 'name')} />
<input type="text" value={age} onChange={this.handleChange.bind(this, 'age',)} />
</div>
);
}
}
export default Controlled;複製代碼
參考:
https://segmentfault.com/a/1190000012404114#articleHeader2
https://react.docschina.org/docs/uncontrolled-components.html