John John - 2 months ago 23
React JSX Question

creating a login component which will show login error

I am creating a login component which will show login error.
But I don't know how to bring

errors
array from
_onSubmit
function to
LoginForm


Here my code the code.

import React, { Component } from 'react';
import Split from 'grommet/components/Split';
import Section from 'grommet/components/Section';
import Sidebar from 'grommet/components/Sidebar';
import LoginForm from 'grommet/components/LoginForm';
//import Logo from './Logo';
import firebase from 'firebase';
export default class Login extends Component {

constructor() {
super();
this._onSubmit = this._onSubmit.bind(this);
this._onResponsive = this._onResponsive.bind(this);
this.state = {responsive: 'multiple',errors:[]};
}

_onSubmit(fields) {


firebase.auth().signInWithEmailAndPassword(fields.username, fields.password).catch(function(error) {
// Handle Errors here.
var errorCode = error.code;
var errorMessage = error.message;
var errors = [];

errors.push(errorCode);
errors.push(errorMessage);
console.log(errors);


// How to bring the errors from here to ??????
});
}

_onResponsive(responsive) {
this.setState({responsive: responsive});
}

render() {

var image;
if ('multiple' === this.state.responsive) {
image = <Section full={true} pad="none" texture="url(img/grafitti.jpg)" />;
}


return (
<Split flex="left" separator={true} onResponsive={this._onResponsive}>
{image}
<Sidebar justify="center" align="center" pad="medium" size="large">
<LoginForm

title="Ferret"
onSubmit={this._onSubmit}
errors={??????} />
</Sidebar>
</Split>
);
}
}


Can anybody give a guide? Thanks!!!

Answer

The issue here is that you are creating closure when you introduce the function within the .catch() handler.

You are correctly binding your this to the _onSubmit function, but from within the closure you created with the function() {}, your this is not bound to the outer scope.

You have the option of using an arrow function, which does not create a lexical this:

firebase
  .auth()
  .signInWithEmailAndPassword(fields.username, fields.password)
  .catch((error) => {
    ...
    // Now works since the arrow function does not create a new lexical this
    this.setState({})
  });

or, you can bind your outer this (the one you are expecting to have a setState() function) to the inner closure:

firebase
  .auth()
  .signInWithEmailAndPassword(fields.username, fields.password)
  .catch(function(error) {
    this.setState({}) // Is now bound to the outer this
  }.bind(this));