Using React hooks that helpful for your Website Development
Using React hooks is one way to increase productivity, speed up development and can become a useful libraries
React Hooks what it is for?
In the dynamic world of front-end web development, staying on the cutting edge of technology is critical. One of the innovative advancements that has changed the way developers approach building user interfaces is the introduction of React Hooks.
Using React hooks is one way to increase productivity and speed up website development. Hooks can be used repeatedly and become useful libraries for certain things that require special handling.
Since its release (React in version 16.8.), React Hooks have been widely adopted and become an integral part of modern React development that allows functional components to manage state, side effects, context, and more, which were traditionally the domain of class components.
Before the introduction of hooks, functional components were stateless and didn't have access to lifecycle methods or local state, making them less capable compared to class components. In this blog post, we will explore the benefits of using React Hooks and how they can improve your React front-end development experience.
React Built-In Hooks
React provides a set of built-in hooks that cover various aspects of component development. Here's a list of the core React hooks:
-
useState
:- Purpose: Allows functional components to have state.
- Example:
const [count, setCount] = useState(0)
-
useEffect
:- Purpose: Handles side effects in functional components (e.g., data fetching, subscriptions).
- Example:
useEffect(() => { // side effect logic here return () => { // cleanup logic here } }, [dependencies])
-
useContext
:- Purpose: Consumes the value of a context.
- Example:
const value = useContext(MyContext)
-
useReducer
:- Purpose: Manages complex state logic with a reducer function.
- Example:
const [state, dispatch] = useReducer(reducer, initialState)
-
useCallback
:- Purpose: Memoizes a callback function to prevent unnecessary re-renders.
- Example:
const memoizedCallback = useCallback(() => { // callback logic }, [dependencies])
-
useMemo
:- Purpose: Memoizes a value to prevent unnecessary calculations.
- Example:
const memoizedValue = useMemo(() => computeExpensiveValue(a, b), [a, b])
-
useRef
:- Purpose: Creates a mutable object that persists across renders and doesn't trigger re-renders when mutated.
- Example:
const myRef = useRef(initialValue)
-
useImperativeHandle
:- Purpose: Customizes the instance value exposed when using
React.forwardRef
. - Example:
useImperativeHandle( ref, () => ({ // values or methods to expose }), [dependencies] )
- Purpose: Customizes the instance value exposed when using
-
useLayoutEffect
:- Purpose: Similar to
useEffect
, but fires synchronously after all DOM mutations. - Example:
useLayoutEffect(() => { // layout effect logic }, [dependencies])
- Purpose: Similar to
-
useDebugValue
:- Purpose: Customizes the label displayed for custom hooks in the React DevTools.
- Example:
useDebugValue(value)
These built-in hooks provide a powerful and flexible foundation for managing state, effects, context, and other aspects of component behavior in React applications. Keep in mind that React may introduce new hooks in future updates, so checking the official React documentation for the latest information is always a good practice.
The decision to use React hooks or not depends on a few factors, and there isn't a one-size-fits-all answer. Here are some considerations that might help you decide when to use hooks and when you might choose not to:
Use Hooks When:
-
Functional Components:
- Use Case: You are working with functional components.
- Why: Hooks are designed to work with functional components and provide stateful logic without the need for class components.
-
State Management:
- Use Case: You need to manage state in your component.
- Why: Hooks, particularly
useState
, provide a concise and expressive way to manage state within functional components.
-
Lifecycle and Side Effects:
- Use Case: You want to perform actions during component lifecycle or manage side effects.
- Why:
useEffect
simplifies handling side effects, replacing lifecycle methods in class components.
-
Code Reusability:
- Use Case: You want to share logic between components.
- Why: Custom hooks enable you to encapsulate and reuse logic across different components, promoting a modular and DRY (Don't Repeat Yourself) codebase.
-
Readability and Maintainability:
- Use Case: You want to write more readable and maintainable code.
- Why: Hooks help to separate concerns and make your functional components more focused and easier to understand.
-
Stateful Logic:
- Use Case: You need to handle complex stateful logic.
- Why: Hooks like
useReducer
are suitable for managing more complex state and logic within your components.
-
Transitioning from Class Components:
- Use Case: You are migrating from class components to functional components.
- Why: Hooks provide a way to use state and side effects in functional components, making the migration smoother.
Avoid Hooks When:
-
Compatibility with Older Code:
- Use Case: You are working on a codebase with a lot of class components.
- Why: If you have a large existing codebase with class components that work well and don't require significant changes, there might not be an immediate need to switch to hooks.
-
Simple Components:
- Use Case: Your components are simple and don't need state or side effects.
- Why: If your components are straightforward and don't require state or side effects, using hooks might add unnecessary complexity.
-
Learning Curve:
- Use Case: Your team is not familiar with hooks, and there's a tight deadline.
- Why: Learning hooks takes some time, and if your team is on a tight schedule, it might be more efficient to stick with class components for the time being.
-
Compatibility Concerns:
- Use Case: You are working on a project with libraries or components that don't support hooks.
- Why: Some older libraries or components might not be compatible with hooks, and switching to hooks might require updating dependencies.
-
Personal or Team Preference:
- Use Case: Your team or you personally prefer class components.
- Why: While hooks offer many advantages, some developers might still prefer the class component syntax. The choice can depend on personal or team preferences.
In general, hooks are the recommended way to handle state and side effects in React applications. However, the decision to use hooks or not might depend on your project's context, existing codebase, and the specific requirements of your components. It's essential to consider the trade-offs and make a decision based on the needs of your project and team.
Use Case of Custom React Hooks
Using node module packages such as NextAuth.js
in our React project required us to use the library integrated into our project. Of course, NextAuth.js has a built-in library for use in the project. For example, they have a library to get the user's current session data and use them in our project, such as restricting a specific page.
This can be implemented in our library which is integrated with NextAuth.js using react hook. Here are the examples of NextAuth.js hooks integrated into the React project:
import { useEffect, useState } from 'react'
import { useSession } from 'next-auth/react'
import { NEXT_SELF } from '@config/endpoint'
import { RAUTH_SIGNIN, RAUTH_SIGNOUT } from '@config/routes'
function useLogin() {
const [profile, setProfile] = useState(null)
const [errorMsg, setErrorMsg] = useState(null)
const { data, status } = useSession({
required: true,
onUnauthenticated() {
return (window.location.href = RAUTH_SIGNIN.href)
}
})
const accessToken = data?.user?.accessToken
const userId = data?.user?.id
useEffect(() => {
if (status === 'authenticated') {
const fetchData = async () => {
const response = await fetch(NEXT_SELF, {
headers: {
'X-Access-Token': accessToken,
'X-User-ID': userId
}
})
const result = await response.json()
if (!profile && result.success && result?.data) {
setProfile(result?.data)
}
if (!result.success && result.errCode && result.errMsg) {
setErrorMsg({ errCode: result.errCode, errMsg: result.errMsg })
}
}
fetchData().catch(console.error)
}
if (errorMsg && errorMsg.errCode === 'ECONNRESET') {
window.location.href = '/504'
} else if (errorMsg && errorMsg.errCode !== '00000') {
window.location.href = RAUTH_SIGNOUT.href
}
})
return { data, status, profile, accessToken, userId, errorMsg }
}
export { useLogin }
I am using React.js for this implementation and some of the React hooks features such as useEffect
, useState
and some JavaScript function such as fetch()
, map()
, find()
, some()
, sort()
,flatMap()
and others.
Here is the Demos: