--- 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觀察。 因為自己很少用到非受控,所以有錯的地方還麻煩多告訴我。