---
tags: react,
disqus: hackmd
---
{%hackmd theme-dark %}
###### tags: `react` `uncontrolled component` `controlled component` `受控組件` `非受控組件`
# React受控與非受控組件
之前一直對受控組件與非受控組件不是分得很清楚。
這邊所提到的組件,是指在form表單內的`<input>`、`<textarea>`、`<select>`的這類元素。
### [受控組件](https://zh-hans.reactjs.org/docs/forms.html#controlled-components)
簡單的說,受控組件就是,就是單一來源,使 React 的 state 成為“唯一數據源”。
```javascript=
class App extends React.Component {
constructor(props) {
super(props);
this.state = { value: 'hello' };
}
render() {
return <input type='text' value={ this.state.value } />;
}
};
```
input的value來源是state,這時候input的值來自state,無法直接更改值。
```javascript=
class App extends React.Component {
constructor(props) {
super(props);
this.state = { value: 'hello' };
this.handleChange = this.handleChange.bind(this);
}
handleChange(e) {
this.setState({value: e.target.value});
}
render() {
return <input type='text' onChange={this.handleChange} value={ this.state.value } />;
}
};
```
如此一來透過`onChange`觸發`handleChange`去更改state的值,而input的value的來源又是來自state。
這就是受控組件。
### [非受控組件](https://zh-hant.reactjs.org/docs/uncontrolled-components.html)
表單的資料是由 DOM 本身所處理的。
可以使用 ref 來從 DOM 節點中獲取表單數據。
```javascript=
class NameForm extends React.Component {
constructor(props) {
super(props);
this.handleSubmit = this.handleSubmit.bind(this);
this.input = React.createRef();
}
handleSubmit(event) {
alert('A name was submitted: ' + this.input.current.value);
event.preventDefault();
}
render() {
return (
<form onSubmit={this.handleSubmit}>
<label>
Name:
<input type="text" ref={this.input} />
</label>
<input type="submit" value="Submit" />
</form>
);
}
}
```
#### [非受控組件的預設值(defaultValue)](https://zh-hant.reactjs.org/docs/uncontrolled-components.html#default-values)
想想看如果想在input上面放置初始值可以怎麼做?
```javascript=
<input type='text' value={'Bob'} />
```
但是如此一來value就被指定了,要更改也要透過onChange的方法,並且把Bob抽出來放到state。
這樣不就變受控組件了!?
這時候可以使用`預設值`
```javascript=
render() {
return (
<form onSubmit={this.handleSubmit}>
<label>
Name:
<input
defaultValue="Bob"
type="text"
ref={this.input} />
</label>
<input type="submit" value="Submit" />
</form>
);
}
```
把Bob放到`defaultValue`,而input後續的value變更就從ref觀察。
因為自己很少用到非受控,所以有錯的地方還麻煩多告訴我。