React Hooks
Hooks allows components to access state and other functionality. Those are simply javascript functions which differ from react functional components. It improves the performance of react application.Hooks are secure, reusable, readable and flexible.
Things to remember:
We have to import hooks before using it
Hooks can call only inside the react component
The below are the main list of built-in hooks available in react
1. useState
useState allows the application to track the state of a component. useState needs a variable to hold the state and a function to update the state.
import { useState } from 'react';
export default function Profile() {
const [profileName, setprofileName] = useState(null);
function handleProfile() {
setprofileName(profileName ? null : "George");
}
return (
<div>
<button onClick={handleProfile}>
{profileName ? `Clear My Name` : "Check My Name" }
</button>
<div>{profileName ? `My Name is ${profileName}` : "" }</div>
</div>
);
}
In the above example const [profileName, setprofileName] = useState(null); profileName is the state variable whose initial value is null and setprofileName is the function to update the value of profileName.
2. useReducer
useReducer is the same as useState.The difference is we can use reducer function to add the custom logic.
import { useReducer } from 'react';
function handleProfile(state, action) {
if (action.type === 'clear') {
return {
profileName: null
};
} else {
return {
profileName: "George"
};
}
}
export default function Profile() {
const [state, dispatch] = useReducer(handleProfile, { profileName: null });
return (
<>
<button onClick={() => {
dispatch({ type: 'clear' })
}}>
Clear My Name
</button>
<button onClick={() => {
dispatch({ type: 'check' })
}}>
Check My Name
</button>
<div>{state.profileName ? `My Name is ${state.profileName}` : "" }</div>
</>
);
}
In the above example const [state, dispatch] = useReducer(handleProfile, { profileName: null }); state is holding current state, dispatch is a function to update the state, handleProfile is reducer function to add custom logics, the initial value can be passed as second param of useReducer. There is an optional third parameter. This will be a function to calculate the initial values.
3. useEffect
useEffect is allowing the react to connect with an external system. If we want to do something on rendering or update some data based on changing dependency value, we can use useEffect.
import { useState, useEffect } from "react";
import React from 'react';
export default function Profile() {
const [profileName, setProfileName] = useState(null);
const [updateCount, setUpdateCount] = useState(0);
useEffect(() => {
setProfileName('George Updated ' + updateCount + 'Times')
}, [updateCount])
function handleProfile() {
setUpdateCount(updateCount + 1)
}
return (
<div>
<button onClick={handleProfile}>
{profileName ? "Clear My Name" : "Check My Profile Status" }
</button>
<div>{profileName ? profileName : "" }</div>
</div>
);
}
useEffect has two arguments. First one is the function for doing logic based on the second dependency argument.
Normally useEffect will run on every render.
useEffect(() => {
})
If we want to run the useEffect only on first render please use empty dependency array
useEffect(() => {
}, [])
If we want to run the useEffect only on first render and at the time dependency change, please use some dependency as second argument.
useEffect(() => {
}, [updateCount])
4. useRef
useRef is used to track the value that is not needed for rendering. It can be used to refer to an HTML input element. useRef returns an object which has current property that will hold the value of ref.
export default function Profile() {
const inputTextValue = useRef("")
const [profile, setProfile] = useState("")
function showProfile() {
setProfile(inputTextValue.current.value)
}
function clearProfile() {
setProfile("")
}
return (
<div>
<input type="text" ref={inputTextValue} id={'profile'} />
<div>Current Name is {profile}</div>
<button onClick={showProfile}>
Check Input
</button>
<button onClick={clearProfile}>
Clear Input
</button>
</div>
);
}
5. useContext
useContext is used to maintain global state. It can be used to pass the value from parent component to child components.
import { useState, createContext, useContext} from "react";
import React from 'react';
const UserContext = createContext();
export default function App(props) {
const [user, setUser] = useState("George");
return (
<UserContext.Provider value={user}>
<h1>{`My Name is ${user}!`}</h1>
<Profile />
</UserContext.Provider>
);
}
export function Profile() {
const user = useContext(UserContext)
return (
<div>
{`Hello again ${user}`}
</div>
);
}
6. useMemo
useMemo is used to cache the return value of a function. If we need to run a function on each render, we can avoid extensive calculation and cache the results for better performance.
import { useState, useMemo } from "react";
import React from 'react';
export function App(props) {
return (
<div className='App'>
{Profile()}
<h1>Hello React.</h1>
<h2>Start editing to see some magic happen!</h2>
</div>
);
}
export default function Profile() {
const [updateCount, setUpdateCount] = useState(0);
function handleProfile() {
setUpdateCount(updateCount + 1)
}
function clearProfile() {
setUpdateCount(updateCount)
}
function checkProfileName () {
return 'George Updated ' + updateCount + 'Times'
}
const profileName = useMemo(() => checkProfileName (), [updateCount]);
return (
<div>
<button onClick={handleProfile}>
Count More
</button>
<button onClick={clearProfile}>No Update</button>
<div>{profileName ? profileName : "" }</div>
</div>
);
}
7. useCallback
Unlike useMemo which is caching function response, useCallback will cache the function itself for the later use. This hook is very useful to prevent the re rendering when the components props are changed.
import { useState, useMemo, useCallback } from "react";
import React from 'react';
export function App(props) {
return (
<div className='App'>
{Profile()}
<h1>Hello React.</h1>
<h2>Start editing to see some magic happen!</h2>
</div>
);
}
export default function Profile() {
const [updateCount, setUpdateCount] = useState(0);
const [updateCall, setUpdateCall] = useState(0);
function handleProfile() {
setUpdateCount(updateCount + 1)
}
function handleCallBack() {
setUpdateCall(updateCall + 1)
}
function clearProfile() {
setUpdateCall(updateCount)
}
const checkProfileName = useCallback(() => {
return 'George Updated ' + updateCount + 'Times'
}, [updateCall])
const profileName = useMemo(() => checkProfileName(), [updateCount]);
return (
<div>
<button onClick={handleProfile}>
Memo
</button>
<button onClick={handleCallBack}>
Call back
</button>
<button onClick={clearProfile}>No Update</button>
<div>{profileName ? profileName : "" }</div>
</div>
);
}