Project Overview
Link: https://altschool-second-semester-exam-sage.vercel.app/
The goal of this project was to create a single web application with react.js.. It should contain the following features
A counter app
404 Page: A custom 404 page to handle route not found scenarios.
Error Boundary: A component to catch JavaScript errors anywhere in the component tree.
The tools i made use of when building include react ,react-router, css, error-boundary.
Project Details
Installation:
I started by creating a react package by running "npx create-react-app counter" on my windows terminal. After this, i installed the react-router-dom in my vs-code terminal by running "npm install react-router-dom"
Implementation:
I started by creating the counter component that maintains and displays a count. I created buttons for both increment and decrement then added functions into them so as to enable them perform their function
return (
<>
<ThemeButton theme={theme} toggleTheme={toggleTheme} />
<div data-aos="fade-up" className="main-container">
<div className="container">
<p>Count: {count}</p>
<div className="buttons">
<button className="increment" onClick={increment}>
Increment
</button>
<button className="decrement" onClick={decrement}>
Decrement
</button>
<button className="reset" onClick={reset}>
Reset
</button>
</div>
<input
type="number"
value={customValue}
onChange={handleCustomValueChange}
/>
<button className="setvalue" onClick={() => setValue(customValue)}>
Set Custom Value
</button>
</div>
<button className="back back-homepage">
<Link to="/">Homepage</Link>
</button>
</div>
</>
);
}
404 Page
The 404 page was done in two ways
I set up the React Router to handle different routes.
I created a custom
NotFound
component for 404 scenarios.
return (
<div data-aos="fade-up" className="error">
<ThemeButton theme={theme} toggleTheme={toggleTheme} />
<h1>404 - Page Not Found</h1>
<p>The page you are looking for does not exist.</p>
<button className="back">
<Link to="/">Homepage</Link>
</button>
</div>
)
Error Boundary
The error boundary was also done in two ways. They include
I created an error test component which was made up of a link to the error boundary page.
I set up my error boundary page with functions from the error test component
//Error Test.js
const navigate = useNavigate();
const handleTestButtonClick = () => {
navigate('/error-success');
};
//Clicked before error boundary page
return (
<div data-aos="fade-up" className='error-div'>
<ThemeButton theme={theme} toggleTheme={toggleTheme}/>
<h1 className='error-boundary'>Error Boundary Test</h1>
<button className='Error-button' onClick={handleTestButtonClick}>Test Error</button>
</div>
);
//Error Boundary page
return (
<div data-aos="fade-up" className="success-container">
<ThemeButton theme={theme} toggleTheme={toggleTheme} />
<h1 className="error-success">
Oops... an error occurred somewhere in the component{" "}
</h1>
<button className="back">
<Link to="/">Homepage</Link>
</button>
</div>
);
After adding this three features, I completed the project and published it using netlify.
Additional Features:
After 1 month, i decided to take a good look at what i had done then i decided to add an additional light theme to it as it was previously dark themed. I add a toggle button which on clicking, changes the theme of the page from black to white and vice versa.
I did this using the createContext react property. The createContext property returned a context object. The context object itself does not hold any information. It represents which context other components read or provide. I did this in my app.js file, then set up its function before passing it as a prop to the all other component
//App.js
const [theme, setTheme] = useState(() => {
return localStorage.getItem('theme') || 'light';
});
const toggleTheme = () => {
setTheme((currentTheme) => {
const newTheme = currentTheme === 'light' ? 'dark' : 'light';
// Store the updated theme preference in local storage
localStorage.setItem('theme', newTheme);
return newTheme;
})
};
useEffect(() => {
Aos.init({ duration: 1000 });
}, []);
return (
<div className="App" id={theme}>
<ThemeContext.Provider value={{ theme, toggleTheme }}>
<BrowserRouter>
<Routes>
<Route
path="/"
exact
element={<Homepage theme={theme} toggleTheme={toggleTheme} />}
/>
<Route
path="/counter"
element={<CounterApp theme={theme} toggleTheme={toggleTheme} />}
/>
<Route
path="error"
element={<ErrorTest theme={theme} toggleTheme={toggleTheme} />}
/>
<Route
path="/error-success"
element={
<ErrorBoundarySuccess theme={theme} toggleTheme={toggleTheme} />
}
/>
<Route path="*" element={<Error />} />
</Routes>
</BrowserRouter>
</ThemeContext.Provider>
</div>
My toggle Button code goes as this
return (
<div>
<div className="dark-button" onClick={toggleTheme}>
{theme === "light" ? (
<img src="Moon.svg" alt="Moon Icon" />
) : (
<img src="Sun.svg" alt="Sun Icon" />
)}
<span>{theme === "light" ? "Dark Mode" : "Light Mode"}</span>
</div>
</div>
);
I later integrated all the components into my parent component which is my app.js component.
///import logo from './logo.svg';
import "./App.css";
import React from "react";
import "aos/dist/aos.css";
import Aos from "aos";
import { useEffect, useState, createContext } from "react";
import { BrowserRouter, Route, Routes } from "react-router-dom";
import Homepage from "./Homepage";
import ErrorTest from "./ErrorTest";
import CounterApp from "./counterlogic/counterapp";
import Error from "./error";
import ErrorBoundarySuccess from "./ErrorBoundarySuccess";
My technical write-up covers the implementation of a simple React web project with a counter, a 404 page, an error boundary, and a dark/white theme toggle button. The project demonstrates the use of React, React Router, and CSS to achieve the specified features. It's a starting point that can be expanded upon for more complex applications.
Link to project :