6 受控组件与非受控组件
受控组件
- 表单的值,受到
state控制 - 需要自行监听
onChange,更新state - 对比非受控组件
import React from 'react'
class FormDemo extends React.Component {
constructor(props) {
super(props)
this.state = {
name: 'test',
info: '个人信息',
city: 'shenzhen',
flag: true,
gender: 'male'
}
}
render() {
// 受控组件
// return <div>
// <p>{this.state.name}</p>
// <label htmlFor="inputName">姓名:</label> {/* 用 htmlFor 代替 for */}
// <input id="inputName" value={this.state.name} onChange={this.onInputChange}/>
// </div>
// textarea - 使用 value
return <div>
<textarea value={this.state.info} onChange={this.onTextareaChange}/>
<p>{this.state.info}</p>
</div>
// // select - 使用 value
// return <div>
// <select value={this.state.city} onChange={this.onSelectChange}>
// <option value="beijing">北京</option>
// <option value="shanghai">上海</option>
// <option value="shenzhen">深圳</option>
// </select>
// <p>{this.state.city}</p>
// </div>
// // checkbox
// return <div>
// <input type="checkbox" checked={this.state.flag} onChange={this.onCheckboxChange}/>
// <p>{this.state.flag.toString()}</p>
// </div>
// // radio
// return <div>
// male <input type="radio" name="gender" value="male" checked={this.state.gender === 'male'} onChange={this.onRadioChange}/>
// female <input type="radio" name="gender" value="female" checked={this.state.gender === 'female'} onChange={this.onRadioChange}/>
// <p>{this.state.gender}</p>
// </div>
// 非受控组件 - 后面再讲
}
onInputChange = (e) => {
this.setState({
name: e.target.value
})
}
onTextareaChange = (e) => {
this.setState({
info: e.target.value
})
}
onSelectChange = (e) => {
this.setState({
city: e.target.value
})
}
onCheckboxChange = () => {
this.setState({
flag: !this.state.flag
})
}
onRadioChange = (e) => {
this.setState({
gender: e.target.value
})
}
}
export default FormDemo
非受控组件
ref访问DOM元素或者某个组件实例的句柄ref有两种使用方式React.createRef()创建ref,通过ref访问DOM元素或者某个组件实例React.forwardRef()函数组件中传递ref,通过ref访问DOM元素或者某个组件实例
ref有两种使用场景defaultValue、defaultChecked- 手动操作
DOM元素
使用场景
- 必须手动操作
DOM元素,setState实现不了 - 文件上传
<input type="file" /> - 某些富文本编辑器,需要传入
DOM元素
import React from 'react'
class App extends React.Component {
constructor(props) {
super(props)
this.state = {
name: 'test',
flag: true,
}
this.nameInputRef = React.createRef() // 创建 ref
this.fileInputRef = React.createRef()
}
render() {
// // input defaultValue
// return <div>
// {/* 使用 defaultValue 而不是 value ,使用 ref */}
// <input defaultValue={this.state.name} ref={this.nameInputRef}/>
// {/* state 并不会随着改变 */}
// <span>state.name: {this.state.name}</span>
// <br/>
// <button onClick={this.alertName}>alert name</button>
// </div>
// // checkbox defaultChecked
// return <div>
// <input
// type="checkbox"
// defaultChecked={this.state.flag}
// />
// </div>
// file
return <div>
<input type="file" ref={this.fileInputRef}/>
<button onClick={this.alertFile}>alert file</button>
</div>
}
alertName = () => {
const elem = this.nameInputRef.current // 通过 ref 获取 DOM 节点
alert(elem.value) // 不是 this.state.name
}
alertFile = () => {
const elem = this.fileInputRef.current // 通过 ref 获取 DOM 节点
alert(elem.files[0].name)
}
}
export default App
