绑定与箭头功能(用于react onClick事件) [英] Binding vs arrow-function (for react onClick event)

查看:77
本文介绍了绑定与箭头功能(用于react onClick事件)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

所以我试图学习反应,并且对构造函数中的 .bind(this)有所了解.但是我想我现在已经了解了,只想知道为什么我会在onClick中使用它与箭头函数.参见下面的代码:

So I am trying to learn react and got a little mixed up with understanding .bind(this) in the constructor. However I think I understand it now and just want to know why I would use that vs an arrow function in the onClick. See code below:

绑定方法可确保eventClick函数中的"this"引用该类

Class Click extends react.Component {
  constructor(props) {
   super(props)
   this.clickEvent = this.clickEvent.bind(this);
  }

  render = () => (
    <button onClick={this.clickEvent}>Click Me</button>
  )

  clickEvent() {console.log(this)} // 'this' refers to the class
}

但是,此方法也引用了该类.有什么优点/缺点可以使用一个相对于另一个?

Class Click extends react.Component {

  render = () => (
    <button onClick={() => {this.clickEvent()}}>Click Me</button>
  )

  clickEvent() {console.log(this)} // 'this' refers to the class
}

推荐答案

首先,让我们看一下每种技术的示例.

First of all, let's see an example of each technique.

import React from 'react';
class MyComponent extends React.Component {
  constructor(props) {
    super(props)
    this.clickHandler = this.clickHandler.bind(this);
  }

  clickHandler() {
    console.log( this )
  }

  render() {
    return <button onClick={this.clickHandler}>Click Me</button>
  }
}

箭头功能:

import React from 'react';
class MyComponent extends React.Component {
  constructor(props) {
    super(props)
  }

  clickHandler = () => {
    console.log( this )
  }

  render() {
    return <button onClick={this.clickHandler}>Click Me</button>
  }
}

优点和缺点:

在公共类字段上使用箭头功能更具可读性,由于更少的代码行,但是请记住,使用箭头功能可能会影响两件事:

Pros and Cons:

Using the Arrow-function on public-class-field is more human-readable, because of fewer lines of code, But keep in mind that using Arrow-function can affect two things:

首先是内存和性能;当您使用类字段定义函数时,整个方法都驻留在该类的每个实例上,而不是在原型上,而是使用 bind 技术,回调存储在每个实例上,该实例调用存储在原型上的方法.

First the memory and performance; When you use a class field to define a function, your whole method resides on each instance of the class and NOT on the prototype, but using the bind technic, just a small callback is stored on each instance, which calls your method that is stored on the prototype.

第二点可能会受到影响的是您编写单元测试的方式.您将无法使用组件原型在如下所示的函数调用上存根:

Second thing that can be affected is how you write your unit tests. You won't be able to use the component prototype to stub on function calls like below:

const spy = jest.spyOn(MyComponent.prototype, 'clickHandler');
// ...
expect(spy).toHaveBeenCalled();

您将不得不找到另一种方法来存根该方法,方法是通过传递道具中的间谍检查状态更改.

You will have to find another way to stub the method, either by passing the spy in props or checking the state changes.

计算机真的很擅长阅读代码.您不必为此担心.您可能要考虑通过使用类属性箭头功能使代码更易于阅读.

Computers are really good at reading code; you shouldn’t worry about that. You may want to consider making your code more human-readable by using a class-property arrow-function.

但是,如果要同时保持人类可读性和性能,请考虑使用 plugin-transform-arrow-functions 插件(尽管 v7.2.0 引起的问题对我来说),只需运行 npm i --save-dev @ babel/plugin-transform-arrow-functions 并将其添加到您的" babel.config.js "或" .babelrc "文件,例如:

But When you want to keep both human-readability and performance, consider using plugin-transform-arrow-functions plugin (although v7.2.0 caused problems for me), just run npm i --save-dev @babel/plugin-transform-arrow-functions and add it into your "babel.config.js" or ".babelrc" file, like:

{
  "presets": ["module:metro-react-native-babel-preset"],
  "plugins": [
    ["@babel/plugin-proposal-decorators", { "decoratorsBeforeExport": false }],
    ["@babel/plugin-transform-arrow-functions", { "spec": true }]
  ]
}

您还可以使用类似自动绑定装饰器的方法,该方法将变为示例进入:

You could also use something like auto-bind decorator, which would turn above example into:

import React from 'react';
import { boundMethod as bind } from 'autobind-decorator';
class MyComponent extends React.Component {
  constructor(props) {
    super(props)
  }

  @bind
  clickHandler() {
    console.log( this )
  }

  render() {
    return <button onClick={this.clickHandler}>Click Me</button>
  }
}

注意:不必在每个函数上都放置 @bind .您只需要绑定传递的函数.例如 onClick = {this.doSomething} fetch.then(this.handleDone)

Note: It is unnecessary to put @bind on every function. You only need to bind functions that you pass around. e.g. onClick={this.doSomething} Or fetch.then(this.handleDone)

这篇关于绑定与箭头功能(用于react onClick事件)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆