0

Buenas tengo una funcion en React y me gustaria pasar this hacia adentro de ella para poder usar los states, alguien sabe como? Muchas gracias por su ayuda

  constructor(props) {
    super(props);
    this.state = {
      message: 'Login'
    }
  }

  componentDidMount(){
  var working = false;
  var y = document.getElementsByClassName('login');
  var login = y[0];

  login.addEventListener('submit', function(e) {
    e.preventDefault();
    if (working) return;
    working = true;
    var state = {};
    state = login.querySelectorAll('button > .state');
    login.classList.add('loading');
    this.setState({message: 'Authenticating'});
    setTimeout(function() {
      login.classList.add('ok');
      this.setState({message: 'Welcome Back!'});
      setTimeout(function() {
        this.setState({message: 'Log In'});
        login.classList.remove('ok loading');
        working = false;
      }, 4000);
    }, 3000);
  });
  }
Santiago D'Antuoni
  • 1,104
  • 4
  • 20
  • 36

1 Answers1

1

Opciones:

En el método componentDidMount define una variable let _this=this; y úsala en el resto de funciones declaradas dentro (las de los setTimeout y la del event listener). Estarás creando una "clausura" (closure, en inglés) que te resolverá el problema.

Otra solución es declarar las funciones con flecha:

 login.addEventListener('submit', (e) => {
    e.preventDefault();
    if (working) return;
    working = true;
    var state = {};
    state = login.querySelectorAll('button > .state');
    login.classList.add('loading');
    this.setState({message: 'Authenticating'});
    setTimeout(() => {
      login.classList.add('ok');
      this.setState({message: 'Welcome Back!'});
      setTimeout(() => {
        this.setState({message: 'Log In'});
        login.classList.remove('ok loading');
        working = false;
      }, 4000);
    }, 3000);
  });

Un pequeño ejemplo con funciones flecha y sin ellas, y un tercer ejemplo de una clausura:

class Test {

  constructor() {
    this.texto="hola";
  }

  metodo() {
   setTimeout(()=>{
    console.log(this.texto);
   });
  }
}

let test=new Test();
test.metodo();

class Test2 {

  constructor() {
    this.texto="no se escribirá nada";
  }

  metodo() {
   setTimeout(function() {
    console.log(this.texto);
   });
  }
}

let test2= new Test2();
test2.metodo();

class Test3 {

  constructor() {
    this.texto="clausura";
  }

  metodo() {
  let _this=this;
   setTimeout(function() {
    console.log(_this.texto);
   });
  }
}

let test3= new Test3();
test3.metodo();
Pablo Lozano
  • 45,934
  • 7
  • 48
  • 87