简体   繁体   中英

myFunction is not a function

I want to call a function and have an error message "this.testFunc is not a function"

I think the problem is that the function is initialised in ComponentDidMount and then testFunc is not defined yet, but I don't know how to solve it.

var _receivedNb = 0

export default class App extends Component {
  constructor(){
    super()
  }

  componentDidMount() {

    BleManager.start({showAlert: false});

    this.handlerUpdate = bleManagerEmitter.addListener('BleManagerDidUpdateValueForCharacteristic', this.handleUpdateValueForCharacteristic );
  }


  handleUpdateValueForCharacteristic(data) {
      _receivedNb = this.testFunc();
  }

  testFunc() {
    var r = 2;
    return r;
  }

You have to bind your event handler

constructor(){
  super()
  this.handleUpdateValueForCharacteristic = this.handleUpdateValueForCharacteristic.bind(this)
}

You should bind that function in constructor. I hope following code will help,

var _receivedNb = 0

export default class App extends Component {
  constructor(props){
    super(props)
    this.testFunc = this.testFunc.bind(this);
  }

  testFunc() {
    var r = 2;
    return r;
  }
  componentDidMount() {

    BleManager.start({showAlert: false});

    this.handlerUpdate = bleManagerEmitter.addListener('BleManagerDidUpdateValueForCharacteristic', this.handleUpdateValueForCharacteristic );
  }


  handleUpdateValueForCharacteristic(data) {
      _receivedNb = this.testFunc();
  }

declare the function handleUpdateValueForCharacteristic as an arrow function in order to let it inherit the outer scope (that is the class scope) and you should be fine.

handleUpdateValueForCharacteristic = data => {
  _receivedNb = this.testFunc();
}

It is because of this reference inside handleUpdateValueForCharacteristic is not what you are thinking. You can learn about this in detail from You Dont Know Js

Coming to the solution there are multiple approaches to resolve this, you need to fix the this reference inside handleUpdateValueForCharacteristic

One easy approach is using ARROW FUNCTION => . Arrow functions preserve this from the location where the function is defined.

var _receivedNb = 0

export default class App extends Component {
    constructor(){
        super()
    }

componentDidMount() {

    BleManager.start({showAlert: false});

    this.handlerUpdate = bleManagerEmitter.addListener('BleManagerDidUpdateValueForCharacteristic', this.handleUpdateValueForCharacteristic );
}


handleUpdateValueForCharacteristic = (data) => {
    _receivedNb = this.testFunc();
}

testFunc = () => {
  var r = 2;
  return r;
}

Second approach is using .call, .bind or .apply . You can read about them later, In short bind takes this in params and return a hard-binded function with this always referring to what was provided inside .bind . You can simply use handleUpdateValueForCharacteristic.bind(this) and call it. The best way to do this is inside constructor .

var _receivedNb = 0

export default class App extends Component {
    constructor(){
        super()  
        this.newHandleUpdateValueForCharacteristic = handleUpdateValueForCharacteristic.bind(this)

    }

componentDidMount() {

    BleManager.start({showAlert: false});

    this.handlerUpdate = bleManagerEmitter.addListener('BleManagerDidUpdateValueForCharacteristic', this.handleUpdateValueForCharacteristic );
}


handleUpdateValueForCharacteristic = (data) => {
    _receivedNb = this.testFunc();
}

testFunc = () => {
  var r = 2;
  return r;
}

and use newHandleUpdateValueForCharacteristic every where else.

Call and apply are similar to bind with only difference that it immediately calls the function with this reference and other required parameters passed inside call and apply.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM