How To Implement React Hooks and Set Input Values in a Counter Application.
Implementing a Counter App with React Hooks: useState and useReducer , Error Boundary and SEO.
Hi š.!!!,
Guess we are both meeting for the first time š...
So, you are most welcome.
A popular quote states:
āEvery moment is a fresh beginning.ā
ā T.S. Eliot
In this article, we are building together a Counter Application leveraging ReactJS as part of AltSchool Africa School of Engineering the Holiday challenge for December '22.
š
OBJECTIVES
By the end of this project, we should have
ā”set up a custom counter hook with increment, decrement, reset and set value functions.
ā”Implemented a combination of states with Reducer that implements the counter with the four evident features in the custom hook above.
ā”implemented a 404 page and a page to test Error boundary with good SEO.
Prerequisites.
To fully grasp the concept being shared today, you need to be familiar with React js, Cascading style sheet(CSS), javascript and a code editor (vs code).
React is a JavaScript Library for building interactive user Interfaces. A newbie like meš¤©?
Take a pause and check out this free React course to have your environment all set up. Other dependables needed to be installed in the terminal are;
React-router-dom
React-error-boundary
React-helmet
DEEP DIVE.
Installation
In windows terminal run the command
npx create-react-app counter-app
cd counter-app
npm start
and cleaned up react app, by deleting files that I would not be needing.Create folders and files for each component of the counter including the two counters as shown below...
useReducerHook
To implement the Reducer hook,
import useReducer from react in the useCounter component,
create a switch statement for increment, decrement, input value and set value as below
set default count state to 0
const defaultState = {
count: 0,
input: "",
};
we set a state and despatch to useReducer
const [state, dispatch] = useReducer(reducerFn, defaultState);
subsequently, we proceed to set handlers for all functions indicated
const incrementHandler = () => {
dispatch({ type: "INCREMENT" });
};
const decrementHandler = () => {
dispatch({ type: "DECREMENT" });
};
const resetHandler = () => {
dispatch({ type: "RESET" });
};
const inputHandler = (e) => {
dispatch({ type: "INPUT_VALUE", payload: e.target.value });
};
const setValueHandler = () => {
dispatch({ type: "SET_VALUE", payload: state.input });
};
return {
state,
incrementHandler,
decrementHandler,
resetHandler,
inputHandler,
setValueHandler,
};
};
export default useCounter;
However to ensure S.E.O, import helmet from react(for search engine Optimization),.as as shown below,
import { Helmet } from "react-helmet-async";
import useCounter from "../hooks/useCounter";
const Counter = () => {
const {
state,
incrementHandler,
decrementHandler,
resetHandler,
inputHandler,
setValueHandler,
} = useCounter();
return (
<div>
<Helmet>
<title>Counter App | OsitaLight</title>
<meta
name="description"
content="Welcome! this is my counter app project"
/>
<link rel="canonical" href="counter" />
</Helmet>
<h1>
Counter: <span>{state.count}</span>
</h1>
<div>
<button onClick={incrementHandler}>+</button>
<button onClick={resetHandler}>Reset</button>
<button onClick={decrementHandler}>-</button>
</div>
<div>
<input
type="number"
placeholder="0"
value={state.input}
onChange={inputHandler}
/>
<button onClick={setValueHandler}>Set value</button>
</div>
</div>
);
};
export default Counter;
Not to be forgotten is the fact that to navigate different pages React Router was used,this was implemented by
importing {Routes,Route} from "react-router-dom"
importing React from react
importing lazy(to aid loading for lagging network),
import React from "react";
import { lazy } from "react";
import { Routes, Route } from "react-router-dom";
const Home = lazy(()=>import("../components/Home"))
const Counter = lazy(()=>import("../components/Counter"))
const PageNotFound = lazy(()=>import("../components/Error"))
const AppRouter = () => {
return (
<div className="main">
<Routes>
<Route path="/" element={<Home />} />
<Route path="counter" element={<Counter />} />
<Route path="*" element={<PageNotFound />} />
</Routes>
</div>
);
};
export default AppRouter;
Error Handling
we install error boundary dependables and import from react Error boundary and use the below ErrorCallback function
import { ErrorBoundary } from react-error-boundary;
function ErrorFallback({error, resetErrorBoundary}) {
return (
<div role="alert">
<p>Something went wrong:</p>
<pre>{error.message}</pre>
<button onClick={resetErrorBoundary}>Try again</button>
</div>
)
}
useState counter value
-Declare React state to store the count value
const [count, setCount] = useState(0);
-set count state to render on the screen,
-declare a JS function to increment,decrement, and set the value of the count
-add buttons with onclick handler to affect all functions
<button onClick={incrementHandler}>+</button>
<button onClick={resetHandler}>Reset</button>
<button onClick={decrementHandler}>-</button>
CHALLENGES
the major challenge I had with this project was implementing the useReducer Counter to display on different pages separate from the useCounter initially had both displayed alongside the other in the App.jsx page š¤£.
EXPERIENCE GAINED
With the aid of this project, I now know how and when to use useState ,useRef and useReducer .This Project also increased my knowledge of SEO though there is still room for improvement.
CONCLUSION
A full view of all implementations and styles can be seen in my GitHub repo Click here. To view, the live project Click Here .
Notably
- āEducation without application is just entertainment.āāTim Sanders
Thanks for taking the time to read this article will be glad to get your feedback as am actively improving my writing and coding skills in the front-end track .