화살표 함수 (공개 클래스 필드)를 클래스 메서드로 사용하는 방법은 무엇입니까?
나는 React와 함께 ES6 클래스를 처음 사용하고 있는데, 이전에는 메소드를 현재 객체에 바인딩했지만 (첫 번째 예 참조) ES6을 통해 클래스 함수를 화살표가있는 클래스 인스턴스에 영구적으로 바인딩 할 수 있습니까? (콜백 함수로 전달할 때 유용합니다.) CoffeeScript에서 가능한 한 오류를 사용하려고하면 오류가 발생합니다.
class SomeClass extends React.Component {
// Instead of this
constructor(){
this.handleInputChange = this.handleInputChange.bind(this)
}
// Can I somehow do this? Am i just getting the syntax wrong?
handleInputChange (val) => {
console.log('selectionMade: ', val);
}
SomeClass.handleInputChange
예를 들어 내가 전달한다면 객체가 setTimeout
아닌 클래스 인스턴스로 범위가 지정됩니다 window
.
구문 이름이 약간 떨어져 속성 이름 뒤에 등호가 없습니다.
class SomeClass extends React.Component {
handleInputChange = (val) => {
console.log('selectionMade: ', val);
}
}
이것은 실험적인 기능입니다. 이것을 컴파일하려면 Babel의 실험 기능을 활성화해야합니다. 다음 은 실험이 가능한 데모입니다.
babel에서 실험 기능을 사용하려면 여기 에서 관련 플러그인을 설치할 수 있습니다 . 이 특정 기능을 사용하려면 transform-class-properties
플러그인 이 필요합니다 .
{
"plugins": [
"transform-class-properties"
]
}
클래스 필드 및 정적 속성 제안에 대한 자세한 내용은 여기를 참조하십시오.
아니요, 바인딩 된 인스턴스 별 메소드를 생성하려면 생성자에서 수행해야합니다. 그러나 .bind
프로토 타입 방법 을 사용 하는 대신 화살표 기능을 사용할 수 있습니다 .
class SomeClass extends React.Component {
constructor() {
super();
this.handleInputChange = (val) => {
console.log('selectionMade: ', val, this);
};
…
}
}
동일한 기능을 사용하여 과제 를 생략하고 과제를 수업 범위에 직접 넣을 수 있는 제안 이 constructor()
있지만 실험적이기 때문에 사용하지 않는 것이 좋습니다.
또는 항상을 사용 .bind
하여 프로토 타입에서 메소드를 선언 한 다음 생성자의 인스턴스에 바인딩 할 수 있습니다. 이 접근법은 클래스 외부에서 메소드를 수정할 수 있으므로 유연성이 더 뛰어납니다.
class SomeClass extends React.Component {
constructor() {
super();
this.handleInputChange = this.handleInputChange.bind(this);
…
}
handleInputChange(val) {
console.log('selectionMade: ', val, this);
}
}
이 질문에 대한 답변이 충분하다는 것을 알고 있지만 실험 기능을 사용하지 않으려는 사람들에게는 약간의 기여를합니다. 생성자에서 여러 함수 바인딩을 바인딩하고 지저분한 것처럼 보이게 만드는 문제 때문에 한 번 생성자에서 바인딩되고 호출 된 유틸리티 메소드가 나타났습니다. 필요한 모든 메소드 바인딩이 자동으로 수행됩니다.
생성자와 함께이 클래스가 있다고 가정합니다.
//src/components/PetEditor.jsx
import React from 'react';
class PetEditor extends React.Component {
constructor(props){
super(props);
this.state = props.currentPet || {tags:[], photoUrls: []};
this.tagInput = null;
this.htmlNode = null;
this.removeTag = this.removeTag.bind(this);
this.handleChange = this.handleChange.bind(this);
this.modifyState = this.modifyState.bind(this);
this.handleKeyUp = this.handleKeyUp.bind(this);
this.addTag = this.addTag.bind(this);
this.removeTag = this.removeTag.bind(this);
this.savePet = this.savePet.bind(this);
this.addPhotoInput = this.addPhotoInput.bind(this);
this.handleSelect = this.handleSelect.bind(this);
}
// ... actual method declarations omitted
}
지저분 해 보이지 않습니까? 이제이 유틸리티 메소드를 만들었습니다.
//src/utils/index.js
/**
* NB: to use this method, you need to bind it to the object instance calling it
*/
export function bindMethodsToSelf(objClass, otherMethodsToIgnore=[]){
const self = this;
Object.getOwnPropertyNames(objClass.prototype)
.forEach(method => {
//skip constructor, render and any overrides of lifecycle methods
if(method.startsWith('component')
|| method==='constructor'
|| method==='render') return;
//any other methods you don't want bound to self
if(otherMethodsToIgnore.indexOf(method)>-1) return;
//bind all other methods to class instance
self[method] = self[method].bind(self);
});
}
All I now need to do is import that utility, and add a call to my constructor, and I don't need to bind each new method in the constructor anymore. New constructor now looks clean, like this:
//src/components/PetEditor.jsx
import React from 'react';
import { bindMethodsToSelf } from '../utils';
class PetEditor extends React.Component {
constructor(props){
super(props);
this.state = props.currentPet || {tags:[], photoUrls: []};
this.tagInput = null;
this.htmlNode = null;
bindMethodsToSelf.bind(this)(PetEditor);
}
// ...
}
You are using arrow function and also binding it in constructor. So you no need to do binding when you use arrow functions
class SomeClass extends React.Component {
handleInputChange = (val) => {
console.log('selectionMade: ', val);
}
}
OR you need to bind a function only in constructor when you use normal function like below
class SomeClass extends React.Component {
constructor(props){
super(props);
this.handleInputChange = this.handleInputChange.bind(this);
}
handleInputChange(val){
console.log('selectionMade: ', val);
}
}
Also binding a function directly in render is not recommended. It should always be in constructor
'Programming' 카테고리의 다른 글
특정 CSS를 조건부로 사용하기 위해 Rails 3.1 자산 파이프 라인 사용 (0) | 2020.05.28 |
---|---|
ASP.Net MVC에서 컨트롤러에서 요청을 조롱하는 방법? (0) | 2020.05.27 |
Webpack.config index.html을 dist 폴더에 복사하는 방법 (0) | 2020.05.26 |
가능한 두 테이블 중 하나에 MySQL 외래 키를 수행 할 수 있습니까? (0) | 2020.05.26 |
AngularJS는 jQuery보다 나은 점은 무엇입니까? (0) | 2020.05.26 |