Try   HackMD
tags: react uncontrolled component controlled component 受控組件 非受控組件

React受控與非受控組件

之前一直對受控組件與非受控組件不是分得很清楚。
這邊所提到的組件,是指在form表單內的<input><textarea><select>的這類元素。

受控組件

簡單的說,受控組件就是,就是單一來源,使 React 的 state 成為“唯一數據源”。

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,無法直接更改值。

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。

這就是受控組件。

非受控組件

表單的資料是由 DOM 本身所處理的。
可以使用 ref 來從 DOM 節點中獲取表單數據。

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)

想想看如果想在input上面放置初始值可以怎麼做?

<input type='text' value={'Bob'} />

但是如此一來value就被指定了,要更改也要透過onChange的方法,並且把Bob抽出來放到state。
這樣不就變受控組件了!?

這時候可以使用預設值

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觀察。

因為自己很少用到非受控,所以有錯的地方還麻煩多告訴我。