This is an article on my second-semester Exam project in Alt School, which is about Building an App that requires authentication from a user in other to log in before using the App. I will be walking you step by step through the process involved in building this app, This project is built with React (A programming language in web development).
The idea behind this Project is to create A Bank Mobile Application that requires a user to log into the application by providing a valid username, and once logged can perform simple transactions which include: sending money to a bank account or recharging a mobile network and also have all details of this transaction stored.
The Functionalities which were Implemented during the course of building this Project include:
Setting up React Router
Implementing Nested Route
Setting up a 404 Page(Page not found)
Setting up Error Boundary
Setting up fake userAuthContext using the context API
Implementation of SEO (search engine optimization) and a Navigation menu that will show on each page.
Extracting out a custom hook to get the currently logged-in user (bonus mark)
Setting up a React Router
React Router is a standard library for routing in React. It enables the navigation among views of various components in a React Application, allows changing the browser URL, and keeps the UI in sync with the URL. To install React Router the following code was executed in the project terminal.
npm install react-router-dom@6
Implementing Nested Route
Nested Route is the ability of a react project to have multiple components rendered on the same page, As the word implies a nested route is a route that is nested inside another route, Put simply a route inside a route, basically the structure of the nested route as implemented is as follows:
<Route>
<Route path="history"
element={
<ProtectedRoute>
<History />
</ProtectedRoute>
}
>
<Route path="nested" element={<MyNest />} />
</Route>
From here the nested Route has the name "MyNest" and it is rendered inside the "History" route.
Setting up a 404 Page (Page not Found)
A 404 page was set up in the application, This is a page that is displayed when a user tries to access a page that does not exist in the application. A 404 page is usually displayed when the user clicks a broken link, the page has been deleted or they've mistyped a URL, A 404 page is a normal react component as shown below
//Displays when you try to access an Invalid Route
import { Link } from "react-router-dom";
const NoMatch = () => {
return (
<div>
<h2 className="error_msg">
<span className="EP">o</span>oops...
</h2>
<img
src="https://media.gettyimages.com/id/468164033/vector/error-404.jpg?s=2048x2048&w=gi&k=20&c=RdSTMxRpODdRsEtDcTfAHr7G1ThGS7slpnl40uvJddY="
alt="Error Page"
width="300px"
height="300px"
className="EI"
/>
<Link className="nested_route" to="/dashboard">
dashboard
</Link>
</div>
);
};
export default NoMatch;
<Route path="*" element={<NoMatch />} />
The asterisk (*) here tells the application to render this component when no match is found i.e trying to access a non-existent page in the application
Setting up Error Boundary
Error Boundary is a React component that catches JavaScript errors anywhere in their child component tree, logs those errors, and displays a fallback UI. It catches errors during rendering or in lifecycle methods. The following is the structure of the error boundary in the application
//Displays when there is an Error in any of the Routes
function ErrorFallback({ error }) {
return (
<div role="alert">
<p>Something went wrong:</p>
<pre>{error.message}</pre>
</div>
);
}
export default ErrorFallback;
<ErrorBoundary FallbackComponent={ErrorFallback}>
<allComponents/>
</ErrorBoundary>
from the code above the Error Boundary is a component that displays the error message of whatever goes wrong in the code, It is used to wrap the whole Application (allComponent) In this way, it can catch errors in any of the components
Setting Up Fake userAuthContext Using The Context API
The fake userAuthContext was used to provide authentication from the user in other to access any of the routes in the application, this authentication was then passed down to the required components as data using the context API.
In other to work properly a protected route (a react component) was used to wrap the components that need authentication. The Authentication requires that valid data is used to log in, after which it takes you to the route using the "navigate" functionality in the protected route
const toker = await fakeAuth();
dispatch({ type: "Token", tok: toker });
const origin = location.state?.from?.pathname || "/About";
navigate(origin);
navigate("/About");
Here a useReducer hook is used to manage different case scenarios and if login is successful the application takes the user to the About Page, but if a login attempt is not successful the application reverts back and persists on the home page, this is enforced by the protected route component as shown below:
//Provides Protection for Routes that should be access only when Authenticated
import { useAuth } from "../App";
import { useLocation } from "react-router-dom";
import { Navigate } from "react-router-dom";
const ProtectedRoute = ({ children }) => {
const { TOKEN } = useAuth();
const location = useLocation();
if (!TOKEN) {
return <Navigate to="/home" replace state={{ from: location }} />;
}
return children;
};
export default ProtectedRoute;
The "TOKEN" here is a passcode that is generated by the context API (from the fakeAuth()) when the login attempt is successful, not TOKEN (!TOKEN) simply means an "unsuccessful login attempt" forcing the application to navigate back to the home component
Implementation of SEO (search engine optimization)
Search engine optimization (SEO) is the art and science of getting pages to rank higher in search engines such as Google, Because search is one of the main ways in which people discover content online, ranking higher in search engines can lead to an increase in traffic to a website.
This was implemented using meta tag and an npm package called "react-helmet-async"
A "helmetProvider" from react-helmet-async was used to wrap the whole application in the root component
import { HelmetProvider } from "react-helmet-async";
<HelmetProvider>
<App />
</HelmetProvider>
Then a Helmet component was used to give a detailed description of each of the components:
import { Helmet } from "react-helmet-async";
<Helmet>
<title>About</title>
<meta
name="description"
content="Give Detailed Description Of The Application"
/>
<link rel="canonical" href="/About" />
</Helmet>
Extracting out a Custom Hook to get the currently logged-in user
A custom Hook was used to get the currently logged-in user as follows:
import { useState } from "react";
//******************************************************//
// An Extracted custom hook to get currently logged in User
const useLog = () => {
const [name, setName] = useState("");
const [text, setText] = useState("");
const handleChange = (e) => {
e.preventDefault();
setName(e.target.value);
if (name !== " ") {
setText("");
}
};
return { name, setName, handleChange, text, setText };
};
//**********************************************************//
export default useLog;
This was then used in the Application as follows
const { name, setName, handleChange, text, setText } = useLog("")
since context API was used to pass data to the all components to avoid prop drilling, this extracted custom hook was subsequently passed as a value to the context API.
const value = {
name,
setName,
handleChange,
TOKEN: state.token,
handleLogin: onLogin,
onLogout: handleLogout,
text,
setText,
FUNDS: state.funds,
FUND: state.fund,
AMOUNT: state.amount,
PHONE: state.phone,
NETWORK: state.network,
DASH: state.dash,
VALUES: state.values,
handle_Input,
Form_Btn,
ACC_AMOUNT: state.account_amount,
ACC_NAME: state.account_name,
ACC_NUMBER: state.account_number,
ACC_TYPE: state.account_type,
ACC_VALUES: state.account_values,
handle_Account_Input,
Form_Acc_Btn,
ACC_ACCESS: state.access,
};
return <AuthContext.Provider value={value}>{children}</AuthContext.Provider>;
Some additional functionalities were added to this project in addition to the validation of user input this includes:
Ensuring that the phone number entered when recharging is a valid phone, as users are expected to enter a correct phone number
setting a minimum amount to recharge as a requirement, this is to enforce standards and ensure stability.
These are all the steps and procedures used to implement the functionalities in building this project, I hope to keep on learning as much as I can, and build better projects in the future!
thanks for reading...