修改状态
通过 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>
)
}
}
|