修改状态
通过 setState 修改状态的写法
- 语法:this.setState({要修改的部分数据})
- 作用:修改state 并更新视图
- 来源:setState() 函数是通过继承来的
- 注意:setState() 的操作是合并,不会影响没有操作到的数据
状态的不可变性
不要直接修改数据,而是要产生一份新的数据,然后通过setState() 用新的数据覆盖原来的数据,这么做的其中一个重要原因就是为了性能优化
受控表单组件
能够使用受控组件的方式收集到表单中的数据
受控不受控一般是针对表单来说的,所谓受控表单组件,即表单元素的value 值受到了 React 中(state)的控制(对状态的操作会影响试图,视图的变化又会反映到状态上)
input
-
在 state 中添加一个状态,作为表单元素的 value 值(数据影响视图)。
-
给表单元素绑定 onChange 事件,将表单元素的值设置为 state 的值(视图影响数据)。
import React from 'react'
export default class App extends React.Component {
state = {
username: '',
}
changeText = (e) => {
this.setState({
username: e.target.value,
})
}
render() {
const { username } = this.state
return (
<ul>
<li>
<label htmlFor='username'>用户名</label>
<input id='username' type='text' value={username} onChange={this.changeText} />
</li>
</ul>
)
}
}
textarea
操作方式和 input 框一样。
import React from 'react'
export default class App extends React.Component {
state = {
content: '',
}
changeTextArea = (e) => {
this.setState({
content: e.target.value,
})
}
render() {
const { content } = this.state
return (
<ul>
{/* ... */}
<li>
<label htmlFor='content'>其他信息</label>
<textarea id='content' cols='30' rows='10' value={content} onChange={this.changeTextArea}></textarea>
</li>
</ul>
)
}
}
select
import React from 'react'
export default class App extends React.Component {
state = {
frame: 'react',
}
changeOption = (e) => {
this.setState({
frame: e.target.value,
})
}
render() {
const { frame } = this.state
return (
<ul>
{/* ... */}
<li>
<label htmlFor='frame'>框架</label>
<select id='frame' value={frame} onChange={this.changeOption}>
<option value='vue'>Vue</option>
<option value='react'>React</option>
<option value='angular'>Angular</option>
</select>
</li>
</ul>
)
}
}
radio
多个单选按钮,绑定的值可以是一个字符串。
export default class App extends React.Component {
state = {
checkedRadio: 'male',
}
changeRadio = (e) => {
this.setState({
checkedRadio: e.target.value,
})
}
render() {
const { checkedRadio } = this.state
return (
<ul>
{/* ... */}
<li>
<input id='male' type='radio' value='male' checked={checkedRadio === 'male'} onChange={this.changeRadio} />
<label htmlFor='male'>男</label>
<input id='female' type='radio' value='female' checked={checkedRadio === 'female'} onChange={this.changeRadio} />
<label htmlFor='female'>女</label>
<input id='unknow' type='radio' value='unknow' checked={checkedRadio === 'unknow'} onChange={this.changeRadio} />
<label htmlFor='unknow'>未知</label>
</li>
</ul>
)
}
}
checkbox
绑定的值可以是一个数组。
import React from 'react'
export default class App extends React.Component {
state = {
username: '',
content: '',
frame: 'react',
checkedRadio: 'male',
checkedFruit: ['apple'],
}
changeText = (e) => {
this.setState({
username: e.target.value,
})
}
changeTextArea = (e) => {
this.setState({
content: e.target.value,
})
}
changeOption = (e) => {
this.setState({
frame: e.target.value,
})
}
changeRadio = (e) => {
this.setState({
checkedRadio: e.target.value,
})
}
changeCheckBox = (e) => {
const checkedFruit = [...this.state.checkedFruit]
const idx = checkedFruit.indexOf(e.target.value)
if (idx === -1) {
// 数组中没有找到,说明没有被选中,那就把数据添加到数组,进行选中的操作
checkedFruit.push(e.target.value)
} else {
// 找到了,说明已被选中,通过删除数组中的数据取消选中
checkedFruit.splice(idx, 1)
}
this.setState({
checkedFruit,
})
}
render() {
const { username, content, frame, checkedRadio, checkedFruit } = this.state
return (
<ul>
<li>
<label htmlFor='username'>用户名</label>
<input id='username' type='text' value={username} onChange={this.changeText} />
</li>
<li>
<label htmlFor='content'>其他信息</label>
<textarea id='content' cols='30' rows='10' value={content} onChange={this.changeTextArea}></textarea>
</li>
<li>
<label htmlFor='frame'>框架</label>
<select id='frame' value={frame} onChange={this.changeOption}>
<option value='vue'>Vue</option>
<option value='react'>React</option>
<option value='angular'>Angular</option>
</select>
</li>
<li>
<input id='male' type='radio' value='male' checked={checkedRadio === 'male'} onChange={this.changeRadio} />
<label htmlFor='male'>男</label>
<input id='female' type='radio' value='female' checked={checkedRadio === 'female'} onChange={this.changeRadio} />
<label htmlFor='female'>女</label>
<input id='unknow' type='radio' value='unknow' checked={checkedRadio === 'unknow'} onChange={this.changeRadio} />
<label htmlFor='unknow'>未知</label>
</li>
<li>
<input id='apple' type='checkbox' value='apple' checked={checkedFruit.includes('apple')} onChange={this.changeCheckBox} />
<label htmlFor='apple'>Apple</label>
<input id='orange' type='checkbox' value='orange' checked={checkedFruit.includes('orange')} onChange={this.changeCheckBox} />
<label htmlFor='orange'>Orange</label>
</li>
</ul>
)
}
}
非受控表单组件
非受控组件则是通过操作DOM 的方式来获取数据,表单中的value 并没有和state 中的数据进行绑定
通过React.createRef() 来获取DOM
在input上绑定ref
import React, { Component } from 'react'
export default class App extends Component {
// Step1
input = React.createRef()
handleChange = () => {
// Step3
console.log(this.input.current.value)
}
render() {
return (
<div>
{/* Step2 */}
<input ref={this.input} type='text' placeholder='输入内容' onChange={this.handleChange} />
</div>
)
}
}