form表單在web應用上很常見,早期作法當使用者填完欄位觸發事件控制,或使用者點擊送出在進行驗證,免不了抓取元素取值驗證。react採取的作法是把元素綁定change事件,每當表單發生變化直接寫入元件的state中,這種元件在react中被稱為受控元件(controlled component)。先總結react受控元件更新state的流程,在比對範例程式就能大致了解整體運作。
src/Form.js
import React, { Component } from 'react';
class Form extends React.Component {
constructor(props) {
super(props);
this.handleInputChange = this.handleInputChange.bind(this);
this.handleRadioChange = this.handleRadioChange.bind(this);
this.handleSelectChange = this.handleSelectChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
this.state = {
inputValue: '',
radioValue: '',
skills: []
};
}
handleInputChange(e) {
this.setState({inputValue: e.target.value.toUpperCase()});
}
handleRadioChange(e) {
this.setState({radioValue: e.target.value});
}
handleSelectChange(e) {
const {options} = e.target;
const skills = Object.keys(options)
.filter(i => options[i].selected === true)
.map(i => options[i].value);
this.setState({skills: skills});
}
handleSubmit(e) {
console.log(this.state);
e.preventDefault();
}
render() {
const {inputValue, radioValue, skills} = this.state;
return (
<form onSubmit={this.handleSubmit} >
<p>
<label>
name:
<input type="text" value={inputValue} onChange={this.handleInputChange}/>
</label>
</p>
<p>
gender
<br/>
<label>
male:
<input type="radio" value="male" checked={radioValue === 'male'}
onChange={this.handleRadioChange}/>
</label>
<label>
female:
<input type="radio" value="female" checked={radioValue === 'female'}
onChange={this.handleRadioChange}/>
</label>
</p>
<p>
skills:
<select multiple={true} value={skills} onChange={this.handleSelectChange}>
<option value="react">react</option>
<option value="vuejs">vuejs</option>
<option value="angular">angular</option>
</select>
</p>
<input type="submit" value="submit" />
</form>
);
}
}
export default Form;
src/index.js
import React from 'react';
import ReactDOM from 'react-dom';
import Form from './Form';
import registerServiceWorker from './registerServiceWorker';
ReactDOM.render(<Form />, document.getElementById('root'));
registerServiceWorker();
輸出結果