React JS + PHP + MySQL DB Login & Registration System

React JS
React JS + PHP + MySQL DB Login & Registration System

Learn how to create a simple Login and Registration System using the React JS, PHP, and MySQL Database. And in this tutorial, instead of redux, we will use the context API.

The purpose of this tutorial is to give an idea of creating a Login and Registration system using React JS & PHP.


Screenshots of this React JS Login & Registration System

React JS Login Page
Login Page
React JS Registration Page
Sign Up Page
React JS Home page after login
After Login (Home) Page

Follow the below to create this React JS & PHP Login System

React JS is used to building user interfaces, so we can’t handle the backend with this. To interact with the backend, we will use the PHP RESTful API.

I have already made a tutorial on how to create PHP login & registration RESTful API. And in this tutorial, I will use that PHP RESTful API. So, you must first check out that.

After making the PHP RESTful API, set up your React CLI Environment & Install Axios package (to perform the ajax requests we will use the Axios JS).

👉 API URLs

// To register a user
http://localhost/php-login-registration-api/register.php

// To log in a user
http://localhost/php-login-registration-api/login.php

// Get User Info by giving token
http://localhost/php-login-registration-api/user-info.php

👉 Creating files & folders

Now we will create our application files and folders. But, before going further let’s take a look at the 📁src folder structure. See the following image –

React JS Login & Registration app src folder structure
Application src folder structure

MyContext.js

First, we will set up our app context. So inside the src folder create a new folder called 📁context, and here we have to create the MyContext.js file.

import React, { createContext,Component } from "react";
import axios from 'axios'
export const MyContext = createContext();

// Define the base URL
const Axios = axios.create({
    baseURL: 'http://localhost/php-login-registration-api/',
});

class MyContextProvider extends Component{
    constructor(){
        super();
        this.isLoggedIn();
    }

    // Root State
    state = {
        showLogin:true,
        isAuth:false,
        theUser:null,
    }
    
    // Toggle between Login & Signup page
    toggleNav = () => {
        const showLogin = !this.state.showLogin;
        this.setState({
            ...this.state,
            showLogin
        })
    }

    // On Click the Log out button
    logoutUser = () => {
        localStorage.removeItem('loginToken');
        this.setState({
            ...this.state,
            isAuth:false
        })
    }

    registerUser = async (user) => {

        // Sending the user registration request
        const register = await Axios.post('register.php',{
            name:user.name,
            email:user.email,
            password:user.password 
        });

        return register.data;
    }


    loginUser = async (user) => {

        // Sending the user Login request
        const login = await Axios.post('login.php',{
            email:user.email,
            password:user.password
        });
        return login.data;
    }

    // Checking user logged in or not
    isLoggedIn = async () => {
        const loginToken = localStorage.getItem('loginToken');

        // If inside the local-storage has the JWT token
        if(loginToken){

            //Adding JWT token to axios default header
            Axios.defaults.headers.common['Authorization'] = 'bearer '+loginToken;

            // Fetching the user information
            const {data} = await Axios.get('user-info.php');

            // If user information is successfully received
            if(data.success && data.user){
                this.setState({
                    ...this.state,
                    isAuth:true,
                    theUser:data.user
                });
            }

        }
    }

    render(){
        const contextValue = {
            rootState:this.state,
            toggleNav:this.toggleNav,
            isLoggedIn:this.isLoggedIn,
            registerUser:this.registerUser,
            loginUser:this.loginUser,
            logoutUser:this.logoutUser
        }
        return(
            <MyContext.Provider value={contextValue}>
                {this.props.children}
            </MyContext.Provider>
        )
    }

}

export default MyContextProvider;

👉 Creating Components

After creating the context file, Now we will create our components. So, again inside the src folder create a new folder called 📁components. And here we will create our components.

In the components folder we have to create three components –

  1. Login.js – Where a user can log in
  2. Register.js – Where a user can Sign up
  3. Home.js – A user can access this page after login.
import React, {useContext, useState} from 'react'
import {MyContext} from '../contexts/MyContext'

function Login(){

    const {toggleNav,loginUser,isLoggedIn} = useContext(MyContext);

    const initialState = {
        userInfo:{
            email:'',
            password:'',
        },
        errorMsg:'',
        successMsg:'',
    }

    const [state,setState] = useState(initialState);

    // On change input value (email & password)
    const onChangeValue = (e) => {
        setState({
            ...state,
            userInfo:{
                ...state.userInfo,
                [e.target.name]:e.target.value
            }
        });
    }

    // On Submit Login From
    const submitForm = async (event) => {
        event.preventDefault();
        const data = await loginUser(state.userInfo);
        if(data.success && data.token){
            setState({
                ...initialState,
            });
            localStorage.setItem('loginToken', data.token);
            await isLoggedIn();
        }
        else{
            setState({
                ...state,
                successMsg:'',
                errorMsg:data.message
            });
        }
    }

    // Show Message on Error or Success
    let successMsg = '';
    let errorMsg = '';
    if(state.errorMsg){
        errorMsg = <div className="error-msg">{state.errorMsg}</div>;
    }
    if(state.successMsg){
        successMsg = <div className="success-msg">{state.successMsg}</div>;
    }



    return(
        <div className="_loginRegister">
            <h1>Login</h1>
            <form  onSubmit={submitForm} noValidate>
                <div className="form-control">
                    <label>Email</label>
                    <input name="email" type="email" required placeholder="Enter your email" value={state.userInfo.email} onChange={onChangeValue} />
                </div>
                <div className="form-control">
                    <label>PassWord</label>
                    <input name="password" type="password" required placeholder="Enter your password" value={state.userInfo.password} onChange={onChangeValue} />
                </div>
                {errorMsg}
                {successMsg}
                <div className="form-control">
                    <button type="submit">Login</button>
                </div>
            </form>
            <div className="_navBtn">
                <button onClick={toggleNav}>Register</button>
            </div>
        </div>
    );
}

export default Login;
import React, {useContext,useState} from 'react'
import {MyContext} from '../contexts/MyContext'

function Register(){
    const {toggleNav,registerUser} = useContext(MyContext);
    const initialState = {
        userInfo:{
            name:'',
            email:'',
            password:'',
        },
        errorMsg:'',
        successMsg:'',
    }
    const [state,setState] = useState(initialState);

    // On Submit the Registration Form
    const submitForm = async (event) => {
        event.preventDefault();
        const data = await registerUser(state.userInfo);
        if(data.success){
            setState({
                ...initialState,
                successMsg:data.message,
            });
        }
        else{
            setState({
                ...state,
                successMsg:'',
                errorMsg:data.message
            });
        }
    }

    // On change the Input Value (name, email, password)
    const onChangeValue = (e) => {
        setState({
            ...state,
            userInfo:{
                ...state.userInfo,
                [e.target.name]:e.target.value
            }
        });
    }
    
    // Show Message on Success or Error
    let successMsg = '';
    let errorMsg = '';
    if(state.errorMsg){
        errorMsg = <div className="error-msg">{state.errorMsg}</div>;
    }
    if(state.successMsg){
        successMsg = <div className="success-msg">{state.successMsg}</div>;
    }

    return(
        <div className="_loginRegister">
            <h1>Sign Up</h1>
            <form onSubmit={submitForm} noValidate>
                <div className="form-control">
                    <label>Full Name</label>
                    <input name="name" required type="text" value={state.userInfo.name} onChange={onChangeValue} placeholder="Enter your name"/>
                </div>
                <div className="form-control">
                    <label>Email</label>
                    <input name="email" required type="email" value={state.userInfo.email} onChange={onChangeValue} placeholder="Enter your email"/>
                </div>
                <div className="form-control">
                    <label>Password</label>
                    <input name="password" required type="password" value={state.userInfo.password} onChange={onChangeValue} placeholder="Enter your password"/>
                </div>
                {errorMsg}
                {successMsg}
                <div className="form-control">
                    <button type="submit">Sign Up</button>
                </div>
            </form>
            <div className="_navBtn">
                <button  onClick={toggleNav}>Login</button>
            </div>
        </div>
    );
}

export default Register
import React, {useContext} from 'react'
import {MyContext} from '../contexts/MyContext'

// Importing the Login & Register Componet
import Login from './Login'
import Register from './Register'

function Home(){

    const {rootState,logoutUser} = useContext(MyContext);
    const {isAuth,theUser,showLogin} = rootState;

    // If user Logged in
    if(isAuth)
    {
        return(
            <div className="userInfo">
                <div className="_img"><span role="img" aria-label="User Image">👦</span></div>
                <h1>{theUser.name}</h1>
                <div className="_email"><span>{theUser.email}</span></div>
                <button onClick={logoutUser}>Logout</button>
            </div>
        )
    }
    // Showing Login Or Register Page According to the condition
    else if(showLogin){
        return <Login/>;
    }
    else{
        return <Register/>;
    }
    
}

export default Home;

App.js

After creating the components, now we have to edit the App.js file –

import React from 'react';
// Importing the Context Provider & Home Component
import MyContextProvider from './contexts/MyContext';
import Home from './components/Home'

function App() {
  return (
    <MyContextProvider>
        <Home/>
    </MyContextProvider>
  );
}

export default App;

index.js

We don’t have to edit this file. Leave it as it is.

import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import * as serviceWorker from './serviceWorker';

ReactDOM.render(<App />, document.getElementById('root'));

// If you want your app to work offline and load faster, you can change
// unregister() to register() below. Note this comes with some pitfalls.
// Learn more about service workers: https://bit.ly/CRA-PWA
serviceWorker.unregister();

index.css

Here is the stylesheet of this application –

*,
*::before,
*::after {
  box-sizing: border-box;
}

body {
  margin: 0;
  font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',
    'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',
    sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  background-color: #f2f2f2;
  padding: 20px;
  color: #3b5441;
}

code {
  font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New',
    monospace;
}

.userInfo,
._loginRegister{
  background-color: #ffffff;
  padding: 20px;
  max-width: 400px;
  margin: 0 auto;
  border-radius: 3px;
  box-shadow: 0 1px rgba(255, 255, 255, .2) inset, 0 2px 2px -1px rgba(0, 0, 0, .3);
}

._loginRegister h1{
  text-align: center;
  margin: 0 0 20px 0;
}

._loginRegister .form-control{
  display: flex;
  flex-wrap: wrap;
  flex-direction: column;
}

._loginRegister .form-control label{
  font-weight: bold;
  margin-bottom: 3px;
}

[type="text"],
[type="email"],
[type="password"]{
  padding:7px 10px;
  outline: none;
  margin-bottom: 5px;
  font-size: 16px;
  border-radius: 2px;
  border: 1px solid rgba(0, 0, 0, .3);
}

[type="text"]:hover,
[type="text"]:focus,
[type="email"]:hover,
[type="email"]:focus,
[type="password"]:hover,
[type="password"]:focus
{
  border-color: #107a8b;
}

._navBtn button,
[type="submit"]{
  background: #ff487e;
  color: #ffffff;
  border: 1px solid rgba(0, 0, 0, .1);
  padding: 10px;
  cursor: pointer;
  font-size: 16px;
  border-radius: 2px;
  margin-top: 5px;
  box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.1), 0 1px 2px 0 rgba(0, 0, 0, 0.06);
  outline: none;
}
._navBtn button:hover,
[type="submit"]:hover{
  opacity: .9;
}

._navBtn{
  border-top: 1px solid #dedede;
  margin-top: 5px;
}
._navBtn button{
  background: #555555;
  color: #ffffff;
  width: 100%;
  
}

.success-msg,
.error-msg{
  border: 1px solid #ff304f;
  padding: 10px;
  color: #ff304f;
  font-weight: bold;
  border-radius: 2px;
}

.success-msg{
  color: #24b273;
  border-color: #24b273;
}

.userInfo{
  text-align: center;
}

.userInfo ._img{
  font-size: 50px;
}
.userInfo h1{
  text-transform: capitalize;
  margin: 10px 0;
}
.userInfo ._email{
  margin: 10px 0;
  color: #555555;
}
.userInfo button{
  margin-top: 5px;
  background: #ff304f;
  color: #ffffff;
  padding: 10px 20px;
  font-size: 16px;
  border: 5px solid rgba(0, 0, 0, .1);
  outline: none;
  border-radius: 3px;
  outline: none;
  cursor: pointer;
  transition: background .3s;
}
.userInfo button:hover{
  border-color: #ff304f;
  color: #ff304f;
  background: #ffffff;
}

Now time to test it. To test this application, execute the npm start command in your terminal.

You May Also Like

4 Comments

  1. Hi bro,
    I have a problem when I try to import the module context, please can you help me?

    this part it’s ok? :
    into login.js –>import {MyContext} from ‘../contexts/MyContext’
    into Mycontext.js –> export const MyContext=createContext();

    I’ll wait for your answer.
    pls, help me

  2. Hello Bro,
    Can you please help me to merge login & registration system and crud with reactjs PHP MySQL as single application.

Leave a Comment

Your email address will not be published. Required fields are marked *