在 HTML 中,表單的 element 像是 、 和 通常會維持它們自身的 state,並根據使用者的輸入來更新 state。
因為 element 中有自己的 state,所以當要抓取 input text 裡面的值,提交(給伺服器,有後端程式跟資料庫)儲存時,方法有兩種:
class NameForm extends React.Component {
constructor(props) {
super(props);
this.handleChange = this.handleChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
this.state = {value: ''};
}
handleChange(event) {
this.setState({value: event.target.value});
}
handleSubmit(event) {
alert('A name was submitted: ' + this.state.value);
event.preventDefault();
}
//直接綁定 value 資料,卻綁 state 與 input 狀態同步
render() {
return (
<form onSubmit={this.handleSubmit}>
<label> Name:
<input type="text" value={this.state.value} onChange={this.handleChange} />
</label>
<input type="submit" value="Submit" />
</form>
);
}}
注:setState 的非同步,可以看到 set 的 console.log 並不會即時顯示 state 最新的值,反而是舊的,
所以可以用 componentDidUpdate 去看他已經更新 (如下圖 DEMO,抓到的資訊可能是還沒更新的)
class Clock extends React.Component {
constructor (props) {
super(props);
this.state = {
words: ''
}
this.handleUpdate = this.handleUpdate.bind(this);
this.input = React.createRef();
}
handleUpdate = () => {
this.setState({
words: this.input.current.value // 直接從 DOM 去抓取資料並存取
})
console.log('set:', this.state.words)
}
componentDidUpdate(prevProps) {
console.log('update:', this.state.words)
}
render() {
return (
<div>
<h1>Hello, Form!</h1>
<form>
<input type="text" onChange={this.handleUpdate} ref={this.input} placeholder="Insert some text" />
</form>
</div>
);
}
}
ReactDOM.render(
<Clock />,
document.getElementById('root')
);
參考資料:
https://zh-hant.reactjs.org/docs/forms.html
Controlled vs Uncontrolled Components in React
https://itnext.io/controlled-vs-uncontrolled-components-in-react-5cd13b2075f9