React-02

118 阅读3分钟
事件绑定 :
  • 在标签中 定义
<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)
}