Can I use arrow function in constructor of a react component?

北慕城南 提交于 2019-11-26 17:52:42

Option 1 is generally more preferable for certain reasons.

class Test extends React.Component{
  constructor(props) {
    super(props);

    this.doSomeThing = this.doSomeThing.bind(this);
  }

  doSomething() {}
}

Prototype method is cleaner to extend. Child class can override or extend doSomething with

doSomething() {
  super.doSomething();
  ...
}

When instance property

this.doSomeThing = () => {};

or ES.next class field

doSomeThing = () => {}

are used instead, calling super.doSomething() is not possible, because the method wasn't defined on the prototype. Overriding it will result in assigning this.doSomeThing property twice, in parent and child constructors.

Prototype methods are also reachable for mixin techniques:

class Foo extends Bar {...}
Foo.prototype.doSomething = Test.prototype.doSomething;

Prototype methods are more testable. They can be spied, stubbed or mocked prior to class instantiation:

spyOn(Foo.prototype, 'doSomething').and.callThrough();

This allows to avoid race conditions in some cases.

I think you may want like this. It is the same with your first situation. it will work in stage-2 with babel. (transform-class-properties : http://babeljs.io/docs/plugins/transform-class-properties/) (preset-stage-2: http://babeljs.io/docs/plugins/preset-stage-2/)

class Test extends React.Component{
  constructor(props) {
    super(props);
  }
  doSomeThing = () => {}
}

Approach 1 is more readable for me and more idiomatic.

Besides, declaring methods inside a class instead of constructor, the methods can be shared.

class Foo {
  test() {}
}

const f1 = new Foo()
const f2 = new Foo()
f1.test === f2.test // true

In approach 2, you will declare all the methods every time you create a new instance:

class Foo {
  constructor() {
    this.test = () => {}
  }
}

const f1 = new Foo()
const f2 = new Foo()
// the method is not shareable
f1.test === f2.test // false

Theoretically the approach 2 is slower, but the impact on performance should be negligible.

I'll simply go for approach 1, since it's used in the React documentation, also I never saw anyone use approach 2.


I just ran some samples to test the performance. In latest Chrome (Mac), declaring methods in constructor is about 90% slower than using bind in constructor.

Check this out:

https://babeljs.io/repl/#?babili=false&evaluate=true&lineWrap=false&presets=es2015%2Creact%2Cstage-2&targets=&browsers=&builtIns=false&debug=false&code=class%20Dog%20%7B%0A%20%20constructor()%20%7B%0A%20%20%20%20%0A%20%20%20%20this.cat%20%3D%20_%3D%3E%20%7B%0A%20%20%20%20%20%20this%0A%20%20%20%20%7D%0A%20%20%7D%0A%7D

We can see babel transpiles

this.doSomeThing = () => { this };

into

var _this = this;
this.doSomething = function() { _this }

edit: I misread your post slightly, but the above is still true and interesting. @CodinCat points out the important thing: declaring a function inside the constructor means it takes time (albeit very little) to add that function to the object when it is created, and also probably takes memory because instances of that class don't share the same doSomeThing method.

edit2: binding (this) to the function actually causes the exact issues I listed above. In other words the two methods are almost exactly the same.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!