Calling setState Asynchronously in React using AJAX

If you follow my blog, you know that I’ve been teaching myself a little ReactJS here over the past week, and for my own personal reference…

Calling setState Asynchronously in React using AJAX

If you follow my blog, you know that I’ve been teaching myself a little ReactJS here over the past week, and for my own personal reference I’ve been publishing some blog posts on how to do various things in React. For this post I’d like to demonstrate how to setState asynchronously in React using AJAX:

index.js

import React from 'react';
import ReactDOM from 'react-dom';
import {
BrowserRouter as Router,
Route,
Link,
Redirect
} from 'react-router-dom';
import Parent from './Parent.js';
ReactDOM.render(<Parent />, document.getElementById('root'));

Parent.js

import React, { Component } from 'react';
/*
*****************************************************************
I'm using react-router in this example to make this tutorial more realistic. In my opinion, React is essentially unusable without a Router of some sort. With that in mind, the idea behind the example is that we submit a username and password to a server using AJAX, and then upon receiving confirmation from the server that the username and password are correct, we <Redirect/> the user from the login component named <Child/> to a home component called <Sibling/> using the react-router.
*****************************************************************
*/

import {
BrowserRouter as Router,
Route,
Link,
Redirect
} from 'react-router-dom';
class Child extends React.Component {
constructor(props) {
super(props);
}
render() {
var loggedIn = this.props.loginProp;
if (loggedIn === false || loggedIn === undefined) {
return (
<div>
<h1>Calling setState Asynchronously with AJAX in React</h1>
<p>Email: <input type="text" onChange={(e) => this.props.onChangeProp1(e)}/></p>
<p>Password: <input type="text" onChange={(e) => this.props.onChangeProp2(e)}/></p>
<p><button onClick={() => this.props.onClickProp()}>Log In</button></p>
</div>
);
} else if (loggedIn === true){
return (
<div>
{/* Redirect to <Sibling/> using react-router */}
<Redirect to="/home"/>
</div>
);
}
}
}
class Sibling extends React.Component {
render() {
return (
<div>
<h1>Calling setState Asynchronously with AJAX in React</h1>
<p>Hello, World! (Login Successful)</p>
</div>
);
}
}
class Parent extends React.Component {
constructor(props) {
super(props);
this.state = {
email: '',
password: '',
loggedIn: false
};
this.handleEmailInput = this.handleEmailInput.bind(this);
this.handlePasswordInput = this.handlePasswordInput.bind(this);
this.login = this.login.bind(this);
}
handleEmailInput(e) {
this.setState({
email: e.target.value
});
}
handlePasswordInput(e) {
this.setState({
password: e.target.value
});
}
login() {
var ajax = new XMLHttpRequest();
// REMEMBER TO CHANGE THE URL BELOW TO MATCH YOUR DOMAIN!
var url = 'http://reactplayground.xyz/login_script.php?email=' + this.state.email + '&password=' + this.state.password + '';
ajax.open("GET", url, true);
ajax.send();
ajax.onreadystatechange = function() {
if (ajax.readyState == 4 && ajax.status == 200) {
var data = ajax.responseText;
data = data.toString();
if (data === "1") { // The server will return "1" if the username and password are correct
this.setState({
loggedIn: true
});
} else { // the server will return "0" if the username and password are incorrect
this.setState({
loggedIn: false
});
alert("ERROR: PC LOAD LETTER");
}
}
}.bind(this) // <-- add .bind(this)
}
  // NOTE: the .bind(this) call above is the tricky part
// of calling setState asynchronously with AJAX in React.
// In fact, this one detail is the main reason I wrote
// this blog post!
render() {
return (
<Router>
<div>
<Switch>
            <Route exact path="/">
<Child
onClickProp={() => this.login()}
onChangeProp1={(e) => this.handleEmailInput(e)}
onChangeProp2={(e) => this.handlePasswordInput(e)}
loginProp={this.state.loggedIn}/>
</Route>
            <Route path="/home">
<Sibling/>
</Route>
          </Switch>
</div>
</Router>
);
}
}
export default Parent;

login_script.php

<?php
$email = $_GET['email'];
$password = $_GET['password'];
if ($email == 'chris@topherpedersen.com' && $password == 'awesomePassword1234') {
// username & password are correct, return "1" for successful login
echo "1";
} else {
// username & password are incorrect, return "0" for unsuccessful login
echo "0";
}
?>

Citation: Making AJAX Requests in React with XHR