事件绑定 :
- 在标签中 定义
<button onClick={this.handleClick}>+1</button>
驼峰命名事件
this问题:
class中的this
- 如果出现this为undefined,代码如下:
class App extends Component {
state = {
count: 0,
}
handleClick() {
// Cannot read properties of undefined (reading 'state')
console.log(this.state.count)
}
render() {
return (
<div>
<h2>计数器:{this.state.count}</h2>
<button onClick={this.handleClick}>+1</button>
</div>
)
}
}
原因:
class App {
handleClick() {
// 类中的函数是开启了严格模式,直接调用 this 就是 undefined
console.log(this) // this ?
}
}
const app = new App()
const onClick = app.handleClick
onClick() // window.onClick()
解决方案:
1.高阶函数/函数柯里化,代码如下.
class App extends React.Component {
state = {
count: 0,
}
handleClick() {
// 这里的 this 指向是什么?那就看是谁调用的!
return () => {
console.log(this.state.count)
}
}
render() {
return (
<div>
<h2>计数器:{this.state.count}</h2>
<button onClick={this.handleClick()}>+1</button>
</div>
)
}
}
(柯里化)通过函数调用,返回的还算函数编码形式, 多次接收参数,最后统一处理的编码形式
2.直接包裹一层箭头函数,代码如下.
class App extends Component {
state = {
count: 0,
}
handleClick() {
console.log(this.state.count)
}
render() {
return (
<div>
<h2>计数器:{this.state.count}</h2>
<button onClick={() => this.handleClick()}>+1</button>
</div>
)
}
}
3.使用bind,代码如下.
class App extends Component {
state = {
count: 0,
}
handleClick() {
console.log(this.state.count)
}
render() {
return (
<div>
<h2>计数器:{this.state.count}</h2>
<button onClick={this.handleClick.bind(this)}>+1</button>//这里的this指向实例
</div>
)
}
}
4. 通过赋值语句往上面添加一个箭头函数,代码如下.
class App extends Component {
state = {
count: 0,
}
handleClick = () => {
console.log(this.state.count)
}
render() {
return (
<div>
<h2>计数器:{this.state.count}</h2>
<button onClick={this.handleClick}>+1</button>
</div>
)
}
}
这是将函数方法 挂载到实例对象身上 如果不写 = 是挂到原型上
5. 在构造函数中创建一个实例方法,和原型方法 共用一个函数体,代码如下.
class App extends React.Component {
constructor() {
super()
this.state = {
count: 0,
}
// 1. 往实例自身上又挂载了一个 handleClick 函数
// 2. 此函数的函数体是通过原型上 handleClick 函数生成的新函数
// 3. 并把原型上 handleClick 函数中的 this 通过 bind 绑定为了 this,而这里构造函数中的 this 正是实例对象
// 4. 其实点击的时候调用的是这个构造函数 handleClick(就近原则),而这个构造函数中的 handleClick 执行的是原型上的 handleClick 的函数体
this.handleClick = this.handleClick.bind(this)
}
handleClick() {
console.log(this.state.count)
}
render() {
return (
<div>
<h2>计数器:{this.state.count}</h2>
<button onClick={this.handleClick}>+1</button>
</div>
)
}
}
实例对象概念
- 实例属性/方法 (1)构造函数
function Person(name, age) {
// this => 实例
// 把 name、age 称为实例属性,因为是挂载到实例上面的
this.name = name
this.age = age
// show 称为实例方法,因为是挂载到实例上面的
this.show = function () {
console.log('Hello React')
}
}
(2)class
class Person {
constructor(name, age) {
// this => 构造函数中的 this 就是就是实例对象!
this.name = name
this.age = age
this.show = function () {
console.log(1)
}
}
// 通过赋值的形式去造出来的是挂载到实例上面的,相当于 #1 处的代码
state = {
age: 88,
}
// 实例方法
handleClick = () => {}
}
- 原型属性/方法 (1)构造函数
function Person(name, age) {
this.name = name
this.age = age
}
Person.prototype.version = 1
Person.prototype.show = function () {
console.log('Hello React')
}
(2)class
class Person {
// 原型方法
handleClick() {}
}
- 静态属性/方法 (1)构造函数
function Person(name, age) {}
// 静态属性
Person.sex = '男'
// 静态方法
Person.test = function () {
console.log('test')
}
(2)class
class Person {
static age = 18
// 静态方法
static handleClick() {}
}
Person.version = 1
关于状态
- React状态 可以通过 setState修改,setState进行修改试图自动更新
- setState 是React.Component上面的方法,它是用来合并,不是覆盖不会影响没有操作到的数据
- 数据状态的不可变性 , 不能直接修改元数据
受控的表单组件
-
状态和value进行绑定,配合onChange事件进行修改。比如 input textare select
-
状态和 checked 进行绑定,配合onChange事件进行修改。比如 radio checkbox
获取非受控控件表单的数据
1 使用ref:
input = React.createRef
2 <input ref={this.input} type='text' onChange={this.handleChange} />
3 事件回调拿到DOM
handleChange = () => {
// Step3
console.log(this.input.current.value)
}