探索React(第四期):React事件

98 阅读3分钟

六月的天,刚诞生的夏天~

React事件和DOM事件

React元素的事件处理和DOM元素的事件处理很相似,只是有一内内语法上的不同。
React事件采用的是小驼峰命名法,而原生事件是纯小写;
React事件需要传入一个函数作为事件处理函数,而原生事件使用的是字符串,其次React事件我们不需要将其执行,而原生事件我们则需要在后面加一对儿();
React事件需要阻止默认行为的时候需要显式的使用e.preventDefault(),而在原生事件中我们则可以使用onclick='javascript:;'。

函数式组件和类组件的写法异同

//函数式组件
 <button onClick={handleDecrease}>-</button>
//==> 等价于
 <button onClick={() => handleDecrease()}>-</button>
//类组件
 <button onClick={this.handleDecrease}>-</button>
//==> 等价于
 <button onClick={() => this.handleDecrease()}>-</button>

this的问题

<button onClick={this.handleDecrease}>-</button>  
handleDecrease() {
   console.log("class--", this);
}

当我们在这段代码中打印this的时候发现this竟然是个undefined,这可还行~
其实这并不是React的锅,而是与javascript的工作原理有关。在javascript中,this的使用方法会随着引用对象的差别而不同,比如说,当我们使用一个对象时,this就会指向这个对象,而如果你是单独函数引用的话,this默认就会指向window对象,而在严格模式中,this就是这个undefined了。

const obj = {
  fun() {
    console.log("fun", this);
  },
};
obj.fun();
//这里的this就是obj这个对象
function test(){
    console.log(this)
}
//这里的this是undefined
setTimeout(function () {
  console.log("this", this);
}, 1000);
//这里的this是window

上述最后一段代码的this指向window是因为setTimeout是window下内置的一个方法,可以接收2个参数,第一个参数允许是一个函数或者一段可执行的js,第二个参数是时间间隔,在上面这段代码中,第一个参数就是一个函数,实际上就是将这个函数的地址当参数传给了setTimeout方法,此时函数的运行就在window对象下了,也就是说函数的调用者已经变成了window对象了。

如何解决this关键字的问题

① 在jsx中使用bind方法
② 在构造函数中使用bind方法
③ 使用箭头函数

<button onClick={this.handleDecrease.bind(this)}>-</button>
//or
constructor(props) {
    super(props);
    this.handleDecrease = this.handleDecrease.bind(this);
}
//or
<button onClick={() => this.handleDecrease()}>-</button>

当然,最建议使用的就是箭头函数啦,这里的this总是指向定义时所在的对象,写起来又简单优雅,绿色又健康 ~ 0v0 ~

传参

我们可以使用bind方法,第一个参数是this关键字,第二个参数就可以传入我们所需要的参数

handleDecrease(props: string) {
    console.log("class--", props);
}
<button onClick={this.handleDecrease.bind(this, "test")}>-</button>

我们还可以使用匿名箭头函数来进行参数的传递

handleDecrease(props: string) {
    console.log("class--", props);
}
<button onClick={() => this.handleDecrease("test")}>-</button>

向父组件传递参数

我们可以从父组件传递给子组件一个方法,让子组件来调用,并将参数传递到这个方法里面,这样我们就可以在父组件中得到子组件传递过来的参数啦。

interface Props {
  handleClick: (id: string) => void;
}
class Son extends Component<Props> {
  render() {
    return (
      <div>
        <button onClick={() => this.props.handleClick("test")}>i am son</button>
      </div>
    );
  }
}

class Parant extends Component {
  handleDecrease(props: string) {
    console.log("son", props);
  }
  render() {
    return (
      <div>
        <Son handleClick={this.handleDecrease} />
      </div>
    );
  }
}