How to use arrow functions (public class fields) as class methods?

前端 未结 4 1124
隐瞒了意图╮
隐瞒了意图╮ 2020-11-21 22:41

I\'m new to using ES6 classes with React, previously I\'ve been binding my methods to the current object (show in first example), but does ES6 allow me to permanently bind a

4条回答
  •  悲&欢浪女
    2020-11-21 23:22

    I know this question has been sufficiently answered, but I just have a small contribution to make (for those who don't want to use the experimental feature). Because of the problem of having to bind multiple function binds in the constructor and making it look messy, I came up with a utility method that once bound and called in the constructor, does all the necessary method bindings for you automatically.

    Assume I have this class with the constructor:

    //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
    }

    It looks messy, doesn't it? Now I created this utility method

    //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);
        }
        // ...
    }

提交回复
热议问题