目录
有状态组件和无状态组件
· 函数组件又叫做无状态组件,类组件又叫做有状态组件
· 状态(state)即数据
· 函数组件没有自己的状态,只负责数据展示(静)
· 类组件有自己的状态,负责更新UI,让页面“动”起来
state的基本使用
· 状态(state)即数据,是组件内部的私有数据,只能在组件内部使用
· state的值是对象,表示一个组件中可以有多个数据
初始化 👇
import React from 'react'
import ReactDOM from 'react-dom'
/*React事件对象*/
class App extends React.Component {
/* constructor() {
super()
//初始化state
this.state = {
count: 0
}
} */
//简化语法初始化state
state = {
count: 0
}
render() {
return (
<div>
<h1>计数器:</h1>
</div>
)
}
}
ReactDOM.render(<App />, document.getElementById('root'))
· 获取状态:this.state
import React from 'react'
import ReactDOM from 'react-dom'
/*React事件对象*/
class App extends React.Component {
/* constructor() {
super()
//初始化state
this.state = {
count: 0
}
} */
//简化语法初始化state
state = {
count: 10
}
render() {
return (
<div>
<h1>计数器:{this.state.count}</h1>
</div>
)
}
}
ReactDOM.render(<App />, document.getElementById('root'))
setState() 修改状态
· 状态是可变的
· 语法:this.setState({要修改的数据})
· 注意:不要直接修改state中的值,这是错误的!!!
· setState()作用:1.修改state 2.更新UI
· 思想:数据驱动视图
import React from 'react';
import ReactDOM from 'react-dom';
class Hello extends React.Component {
constructor() {
super()
this.state = {
count: 0
}
}
render() {
return (<div>
<p>计数器:{this.state.count}</p>
<button onClick={()=>{
this.setState({
count: this.state.count + 1
})
}}>+1</button>
</div>)
}
}
export default Hello
从JSX中抽离事件处理程序
· JSX中掺杂过多JS逻辑代码,会显得非常混乱
· 推荐:将逻辑抽离到单独的方法中,保证JSX结构清晰
· 原因:事件处理程序中this的值为undefined
· 希望:this指向组件实例(render方法中的this即为组件实例)
事件绑定this指向
1.箭头函数
· 利用箭头函数自身不绑定this的特点
· render() 方法中的this为组件实例,可以获取到setState()
import React from 'react'
import ReactDOM from 'react-dom'
/*React事件对象*/
class App extends React.Component {
//简化语法初始化state
state = {
count: 0
}
//事件处理程序
onIncrement() {
this.setState({
count: this.state.count + 1
})
}
render() {
return (
<div>
<h1>计数器:{this.state.count}</h1>
<button onClick={() => this.onIncrement()}>+1</button>
{/* <button onClick={this.onIncrement}></button> */}
{/* <button onClick={() => {
this.setState({
count: this.state.count + 1
})
}}>+1</button> */}
</div>
)
}
}
ReactDOM.render(<App />, document.getElementById('root'))
2.Function.prototype.bind()
· 利用ES5中的bind方法,将事件处理程序中的this与组件实例绑定到一起
import React from 'react'
import ReactDOM from 'react-dom'
/*React事件对象*/
class App extends React.Component {
//简化语法初始化state
state = {
count: 0
}
constructor() {
super()
this.onIncrement = this.onIncrement.bind(this)
}
//事件处理程序
onIncrement() {
console.log('事件处理程序中的this:', this)
this.setState({
count: this.state.count + 1
})
}
render() {
return (
<div>
<h1>计数器:{this.state.count}</h1>
<button onClick={this.onIncrement}>+1</button>
</div>
)
}
}
ReactDOM.render(<App />, document.getElementById('root'))
3.class的实例方法(推荐!!!)
· 利用箭头函数形式的class实例方法
· 注意:该语法是实验性语法,但是,由于babel的存在可以直接使用
表单处理
1.受控组件
· HTML中的表单元素是可输入的,也就是有自己的可变状态
· 而,React中可变状态通常保存在state中,并且只能通过setState()方法来修改
· React将state与表单元素值value绑定到一起,由state的值来控制表单元素的值
· 受控组件:其值受到React控制的表单元素
步骤:
1.在state中添加一个状态,作为表单元素的value值(控制表单元素值的来源)
2.给表单元素绑定change事件,将表单元素的值设置为state的值(控制表单元素值的变化)
import React from 'react'
import ReactDOM from 'react-dom'
/*React事件对象*/
class App extends React.Component {
//简化语法初始化state
state = {
txt: ''
}
handleChange = e => {
this.setState({
txt: e.target.value
})
}
render() {
return (
<div>
<input type="text" value={this.state.txt} onChange={this.handleChange} />
</div>
)
}
}
//渲染组件
ReactDOM.render(<App />, document.getElementById('root'))
多元素表单👇
import React from 'react';
import ReactDOM from 'react-dom';
class Hello extends React.Component {
state = {
txt: '',
content: '',
city:'',
isChecked:false
}
// 处理文本框的变化
handleChange = e => {
this.setState({
txt: e.target.value
})
}
// 处理富文本框的变化
handleContent = e => {
this.setState({
content: e.target.value
})
}
// 处理下拉框的变化
handleCity = e => {
this.setState({
city: e.target.value
})
}
// 处理复选框的变化
handleChecked = e => {
this.setState({
isChecked: e.target.checked
})
}
render() {
return (<div>
{/* 文本框 */}
<input type="text" value={this.state.txt} onChange={this.handleChange}/><br/><br/>
{/* 富文本框 */}
<textarea value={this.state.content} onChange={this.handleContent}></textarea><br/>
{/* 下拉框 */}
<select value={this.state.city} onChange={this.handleCity}>
<option value="cz">滁州</option>
<option value="wx">无锡</option>
<option value="yz">扬州</option>
<option value="nj">南京</option>
</select><br/>
{/* 复选框 */}
<input type="checkbox" checked={this.state.isChecked} onChange={this.handleChecked} />
</div>)
}
}
export default Hello
多表单元素优化:
· 问题:每个表单元素都有一个单独的事件处理程序太繁琐
· 优化:使用一个事件处理程序同时处理多个表单元素
多表单元素优化步骤:
1.给表单元素添加name属性,名称与state相同
2.根据表单元素类型获取对应值
3.在change事件处理程序中通过[name]来修改对应的state
多表单元素优化后👇
import React from 'react';
import ReactDOM from 'react-dom';
class Hello extends React.Component {
state = {
txt: '',
content: '',
city:'',
isChecked:false
}
handleForm = e => {
// 获取当前DOM对象
const target = e.target
//根据类型获取值
const value = target.type === 'checkbox'
? target.checked
: target.value
// 获取name
const name = target.name
this.setState({
[name]: value
})
}
render() {
return (<div>
{/* 文本框 */}
<input type="text" name="txt" value={this.state.txt} onChange={this.handleForm}/><br/><br/>
{/* 富文本框 */}
<textarea value={this.state.content} name="content" onChange={this.handleForm}></textarea><br/>
{/* 下拉框 */}
<select value={this.state.city} name="city" onChange={this.handleForm}>
<option value="cz">滁州</option>
<option value="wx">无锡</option>
<option value="yz">扬州</option>
<option value="nj">南京</option>
</select><br/>
{/* 复选框 */}
<input type="checkbox" checked={this.state.isChecked} name="isChecked" onChange={this.handleForm} />
</div>)
}
}
export default Hello
2.非受控组件(DOM方式)
· 说明:借助于ref,使用原生DOM方式来获取表单元素值
· ref的作用:获取DOM或组件
import React from 'react';
import ReactDOM from 'react-dom';
// 非受控组件
class Hello extends React.Component {
constructor() {
super()
//创建ref
this.txtRef = React.createRef()
}
// 获取文本框的值
getTxt = () => {
console.log('文本框值为:', this.txtRef.current.value);
}
render() {
return (
<div>
<input type="text" ref={this.txtRef} />
<button onClick={this.getTxt}>获取文本框的值</button>
</div>
)
}
}
export default Hello