ReactJS Simple Project with MySQL and PHP

A very simple project with session using reactJS, MySQL and PHP is shown in this tutorial. This tutorial will help you learn the way of fetching data from MySQL using PHP and reactjs, display the data in front page and  implement the authentication system.

Steps:

1. Create a database named reactdb that will contain two tables named books and users. You can download the SQL file of the database from the following link.

reactdb.sql

2. Go to the htdocs folder from command prompt and run the following command to create a new reactjs app named react_book.

create-react-app react_book

3. Go to src folder of react_book and create the following folders.

  • src
    • styles
    • services
    • components
      • Home
      • Welcome
      • Header
      • Footer
      • Login
      • Signup
      • NotFound

4. Download and create the following css files under styles folder.

custom.css
foundation.min.css

5. Run the following command for routing

npm install react-router-dom

6. Create Header.css with the following code under Header folder.

.headcolor
{
background-color:#00D5FF;
}
#tit{
color: white;
font-size: 35px;
}
#head{
	height: 50px;
}
#button{
	text-align: right;
}
#l,#s{
	color:white;
	padding-left: 20px;
}

7. Create Header.js with the following code under Header folder.

import React, { Component } from 'react';
import './Header.css';
class Header extends Component {
render() {
return (
<div className="callout headcolor" id="Header">
<div className="row column">
<div className="medium-8 columns" id="head">
<a href="/"><h1 id="tit">{this.props.name}</h1></a>
</div>
<div className="medium-4 columns" id="button">
<a href="/login" id="l" >Login</a><a href="/signup" id="s" >Signup</a>
</div>
</div>
</div>
);
}
}
export default Header;

8. Create Footer.js with the following code under Footer folder.

import React, {Component} from 'react';
class Footer extends Component {
render() {
return (
<div className="row" id="footer">
<div className="medium-12 columns">
<p align="center">Copyright 2020 , <a href="https://fahmidasclassroom.com"> fahmidasclassroom</a></p>
</div>
</div>
);
}
}
export default Footer;

9. Create Welcome.css with the following code under Welcome folder.

#welcomeText{
font-weight: bold;
font-size: 50px;
text-align: center;
}
#book{
	padding-top: 20px;
	padding-left: 40px;
	padding-bottom: 20px;
}
#body{
	margin: 5% auto;
    min-height: 500px;
}

10. Create Welcome.js with the following code under Welcome folder.

import React, {Component} from 'react';
import './Welcome.css';
import {PostData} from '../../services/PostData';

class Welcome extends Component {
constructor(props) {
	
	super(props);
	this.state = {
		data:[],
	};
}
componentWillMount() {
	this.getbookList();
}
getbookList() {
	PostData('booklist','').then((result) => {
	let responseJson = result;

	if(responseJson.booklist){
		this.setState({data: responseJson.booklist});
		console.log(this.state.data);
	}
	});
}
render() {
	return (<div className="row " id="body">
<div className="medium-12 columns">
<h2 id="welcomeText">Popular Online Books</h2>

{this.state.data.map((item, index) => (
<div className="medium-4 columns" id="book"> 
<b>{item.bookname}</b><br/>
{item.authorname}
</div>
))}
</div>
</div>
);
}
}
export default Welcome;

11. Create NotFound.js with the following code under NotFound folder.

import React, {Component} from 'react';
class NotFound extends Component {
render() {
return (
<div className="row small-up-2 medium-up-3 large-up-4" id="Body">
<div className="medium-12 columns">
<h2>404 Page</h2>
</div>
</div>
);
}
}
export default NotFound;

12. Create routes.js file under src folder and add the following code.

import React from 'react';
import {BrowserRouter, Route, Switch} from 'react-router-dom';
import Welcome from '././components/Welcome/Welcome';
import NotFound from '././components/NotFound/NotFound';

const Routes = () => (
<BrowserRouter >
<Switch>
<Route exact path="/" component={Welcome}/>
<Route path="*" component={NotFound}/>
</Switch>
</BrowserRouter>
);

export default Routes;

13. Modify app.js with the following code.

import React, { Component } from 'react';
import './styles/foundation.min.css';
import './styles/custom.css';
import Routes from './routes';
import Header from './components/Header/Header';
import Footer from './components/Footer/Footer';

class App extends Component {
constructor(){
super();
this.state={
appName: "ReactJS book Example",
home: false
}
}
render() {
return (
<div className="off-canvas-wrapper">
<div className="off-canvas-wrapper-inner" data-off-canvas-wrapper>
<div className="off-canvas-content" data-off-canvas-content>

<Header name={this.state.appName}/>
<Routes name={this.state.appName}/>
<hr/>
<Footer/>
</div>
</div>
</div>
);
}
}
export default App;

14. Add PostData.js under services folder.

export function PostData(type, userData) {
let BaseURL = 'http://localhost/react_book/api/index.php';
return new Promise((resolve, reject) =>{

fetch(BaseURL+'?tp='+type,
{

method: 'POST',
headers:
{
'Accept': 'application/json',
'Content-Type': 'application/json'
},
body:JSON.stringify(userData)
})
.then((response) => response.json()
.then((res) => {
resolve(res);
}))
.catch((error) => {
reject(error);
});
});
}

15. Browse the app from the browser.

16. Create Signup.js with the following code under Signup folder.

import React, {Component} from 'react';
import {PostData} from '../../services/PostData';
import {Redirect} from 'react-router-dom';
class Signup extends Component {
constructor(props){
super(props);
this.state = {
username: '',
password: '',
email: '',
name: '',
redirectToReferrer: false
};
this.signup = this.signup.bind(this);
this.onChange = this.onChange.bind(this);
}

signup() {
if(this.state.username && this.state.password && this.state.email && this.state.name){
PostData('signup',this.state).then((result) => {
let responseJson = result;
if(responseJson.userData){
sessionStorage.setItem('userData',JSON.stringify(responseJson));
this.setState({redirectToReferrer: true});
}
else
alert(result.error);
});
}
}
onChange(e){
this.setState({[e.target.name]:e.target.value});
}
render() {
if (this.state.redirectToReferrer || sessionStorage.getItem('userData')) {
return (<Redirect to={'/home'}/>)
}
return (
<div className="row " id="sBody">
<div className="medium-5 columns left">
<h4>Signup</h4>
<input type="text" name="email" placeholder="Email" onChange={this.onChange}/>
<input type="text" name="name" placeholder="Name" onChange={this.onChange}/>
<input type="text" name="username" placeholder="Username" onChange={this.onChange}/>
<input type="password" name="password" placeholder="Password" onChange={this.onChange}/>
<input type="submit" className="button" value="Sign Up" onClick={this.signup}/>
<a href="/login">Login</a>
</div>
</div>
);
}
}
export default Signup;

17. Create Login.js with the following code under Login folder.

import React, {Component} from 'react';
import {Redirect} from 'react-router-dom';
import {PostData} from '../../services/PostData';
class Login extends Component {
constructor(){
super();
this.state = {
username: '',
password: '',
redirectToReferrer: false
};
this.login = this.login.bind(this);
this.onChange = this.onChange.bind(this);
}
login() {
if(this.state.username && this.state.password){
PostData('login',this.state).then((result) => {
let responseJson = result;
if(responseJson.userData){
sessionStorage.setItem('userData',JSON.stringify(responseJson));
this.setState({redirectToReferrer: true});
}
else
alert(result.error);
});
}
}
onChange(e){
this.setState({[e.target.name]:e.target.value});
}
render() {
if (this.state.redirectToReferrer) {
return (<Redirect to={'/home'}/>)
}
if(sessionStorage.getItem('userData')){
return (<Redirect to={'/home'}/>)
}
return (
<div className="row" id="Body">
<div className="medium-5 columns left">
<h4>Login</h4>
<input type="text" name="username" placeholder="Username" onChange={this.onChange}/>
<input type="password" name="password" placeholder="Password" onChange={this.onChange}/>
<input type="submit" className="button" value="Login" onClick={this.login}/>
<a href="/signup">Registration</a>
</div>
</div>
);
}
}
export default Login;

18. Create Home.css with the following code under Home folder.

.logout{
float:right;
margin:10px 0px;
}

19. Create Home.js with the following code under Home folder.

import React, {Component} from 'react';
import {Redirect} from 'react-router-dom';
import './Home.css';
class Home extends Component {
constructor(props) {
super(props);
this.state = {
data:[],
user:'',
redirectToReferrer: false,
};
this.logout = this.logout.bind(this);
}
componentWillMount() {
if(sessionStorage.getItem("userData")){
let data = JSON.parse(sessionStorage.getItem("userData"));
this.setState({user:data.userData.name});
}
else{
this.setState({redirectToReferrer: true});
}
}
logout(){
sessionStorage.setItem("userData",'');
sessionStorage.clear();
this.setState({redirectToReferrer: true});
}
render() {
if (this.state.redirectToReferrer) {
return (<Redirect to={'/login'}/>)
}
return (
<div className="row" id="body">
<div className="medium-12 columns">
<a href="#" onClick={this.logout} className="logout">Logout</a>
<h3>Welcome {this.state.user}!</h3>
</div>

</div>
);
}
}
export default Home;

20. Modify the routes.js

import React from 'react';
import {BrowserRouter, Route, Switch} from 'react-router-dom';
import Welcome from '././components/Welcome/Welcome';
import Home from '././components/Home/Home';
import Login from '././components/Login/Login';
import Signup from '././components/Signup/Signup';
import NotFound from '././components/NotFound/NotFound';

const Routes = () => (
<BrowserRouter >
<Switch>
<Route exact path="/" component={Welcome}/>
<Route path="/home" component={Home}/>
<Route path="/login" component={Login}/>
<Route path="/Signup" component={Signup}/>
<Route path="*" component={NotFound}/>
</Switch>
</BrowserRouter>
);
export default Routes;

21. Run the app from the browser.

22. Create a folder api under react-book.

23. Go to api folder and create .htaccess file with the following code

RewriteEngine On
#RewriteBase /api/
Header add Access-Control-Allow-Origin "*"
Header add Access-Control-Allow-Headers "origin, x-requested-with, content-type"
Header add Access-Control-Allow-Methods "PUT, GET, POST, DELETE, OPTIONS"
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ index.php [QSA,L]

24. Create a php file named config.php under api folder for database connection and add the following code.

<?php
$db = new mysqli("localhost","root","","reactdb");
if(!$db) die("database connection error");
?>

25. Create index.php under api folder and add the following code

<?php 
$type = $_GET['tp']; 
if($type=='signup') signup(); 
elseif($type=='login') login(); 
elseif($type=='booklist') booklist(); 
function login() 
{ 
       require 'config.php'; 
       $json = json_decode(file_get_contents('php://input'), true); 
       $username = $json['username']; $password = $json['password']; 
       $userData =''; $query = "select * from users where username='$username' and password='$password'"; 
       $result= $db->query($query);
       $rowCount=$result->num_rows;  
       if($rowCount>0)
       {
            $userData = $result->fetch_object();
            $user_id=$userData->user_id;
            $userData = json_encode($userData);
            echo '{"userData":'.$userData.'}';
       }
       else 
       {
            echo '{"error":"Wrong username and password"}';
       }    
}
function signup() {
    
       require 'config.php';
    
       $json = json_decode(file_get_contents('php://input'), true);
       $username = $json['username'];
       $password = $json['password'];
       $email = $json['email'];
       $name = $json['name'];

        $username_check = preg_match("/^[A-Za-z0-9_]{4,10}$/i", $username);
        $email_check = preg_match('/^[a-zA-Z0-9._-]+@[a-zA-Z0-9._-]+\.([a-zA-Z]{2,4})$/i', $email);
        $password_check = preg_match('/^[A-Za-z0-9!@#$%^&*()_]{4,20}$/i', $password);
       
        if($username_check==0) 
            echo '{"error":"Invalid username"}';
        elseif($email_check==0) 
            echo '{"error":"Invalid email"}';
        elseif($password_check ==0) 
            echo '{"error":"Invalid password"}';

        elseif (strlen(trim($username))>0 && strlen(trim($password))>0 && strlen(trim($email))>0 && 
            $email_check>0 && $username_check>0 && $password_check>0)
        {
           
            $userData = '';
            
            $result = $db->query("select * from users where username='$username' or email='$email'");
            $rowCount=$result->num_rows;
            //echo '{"text": "'.$rowCount.'"}';
           
            if($rowCount==0)
            {                    
                $db->query("INSERT INTO users(username,password,email,name)
                            VALUES('$username','$password','$email','$name')");

                $userData ='';
                $query = "select * from users where username='$username' and password='$password'";
                $result= $db->query($query);
                $userData = $result->fetch_object();
                $user_id=$userData->user_id;
                $userData = json_encode($userData);
                echo '{"userData":'.$userData.'}';
            } 
            else {
               echo '{"error":"username or email exists"}';
            }

        }
        else{
            echo '{"text":"Enter valid data2"}';
        }
}

function booklist(){
    require 'config.php';
    $json = json_decode(file_get_contents('php://input'), true);
    //$user_id=$json['user_id'];
    
    $query = "SELECT * FROM books ORDER BY id ASC LIMIT 10";
    //$query = "SELECT * FROM feed ";
    $result = $db->query($query); 

    $bookData = mysqli_fetch_all($result,MYSQLI_ASSOC);
    $bookData=json_encode($bookData);
    echo '{"booklist":'.$bookData.'}';
}
?>

26.Run the app from the browser.

I hope, this tutorial will help you to start web development task using reactjs, php and MySQL.