Table of contents
- Password Generator project
- Step wise explanation :
- HOOK - useCallback
- HOOK - useEffect
- Note , In this basically i want to say that the first default call will go for setPassword so that password generate and visible in input box after that when any change will occur in the dependencies that we have provided then this useEffect will call otherwise not this save us to call for infinite times .
- Handle copy
- Another code without useCallback
Password Generator project
In this project we want something like that ,
So , In this project we can generate the password based on our required length , if we change the length the password will change , similary we can add number inside the password this automatically generate the new password ,similary for characters .Extra thing i have added is that you can copy the password with copy button.
import { useCallback, useEffect, useState } from 'react';
function App() {
const [length, setLength] = useState(8);
const [numberAllowed, setNumberAllowed] = useState(false);
const [characterAllowed, setCharacterAllowed] = useState(false);
const [password, setPassword] = useState('');
const passwordGenerator = useCallback(() => {
let pass = '';
let str = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';
if (numberAllowed) {
str += '0123456789';
}
if (characterAllowed) {
str += '~!@#$%^&*()_±={}|[]:';
}
for (let i = 1; i <= length; i++) {
let char = Math.floor(Math.random() * str.length + 1);
pass += str.charAt(char);
}
setPassword(pass);
}, [length, numberAllowed, characterAllowed]);
const handleCopy = () => {
navigator.clipboard.writeText(password);
};
useEffect(()=>{
passwordGenerator();
},[length,numberAllowed,characterAllowed]);
return (
<>
<div className="flex justify-center items-center min-h-screen bg-gray-100">
<div className="w-2/4 p-6 bg-white rounded-lg shadow-md">
<h1 className="text-3xl font-bold mb-4 text-center">Password Generator</h1>
<div className="flex mb-4">
<input
type="text"
value={password}
className="border rounded px-4 py-2 w-full mr-2"
placeholder="Password"
readOnly
/>
<button
className="bg-blue-500 text-white px-4 py-2 rounded"
onClick={handleCopy}
>
Copy
</button>
</div>
<div className="mb-4">
<input
type="range"
value={length}
min={6}
max={100}
onChange={(e) => setLength(e.target.value)}
className="w-full"
/>
<label className="block">Length: {length}</label>
<input
type="checkbox"
defaultChecked={numberAllowed}
onChange={() => setNumberAllowed((prev)=>!prev)}
className="mr-2"
/>
<label className="mr-4">Numbers</label>
<input
type="checkbox"
defaultChecked={characterAllowed}
onChange={() => setCharacterAllowed((prev)=>!prev)}
className="mr-2"
/>
<label>Characters</label>
</div>
</div>
</div>
</>
);
}
export default App;
Step wise explanation :
So you can see there are 4 useState used that are length , number , character, and password .
These all are changing that’s why we used as hook so that they can update themselves.
HOOK - useCallback
useCallback
is a hook provided by React that memoizes a callback function, which means it returns a memoized version of the callback function that only changes if one of the dependencies has changed.
In the above code:
passwordGenerator
is a memoized callback function. It's a function responsible for generating a password based on certain conditions.Inside the function, it initializes two variables
pass
andstr
.pass
will hold the generated password, andstr
contains the characters from which the password will be generated.Depending on the state of
numberAllowed
andcharacterAllowed
, it appends additional characters tostr
.Then it enters a loop from 1 to the desired
length
of the password. In each iteration, it generates a random character from thestr
and appends it topass
.Finally, it sets the generated password using
setPassword
.The
useCallback
hook is used here to prevent unnecessary re-renders of the component caused by thepasswordGenerator
function. It will only recreate the function when one of its dependencies (length
,numberAllowed
,characterAllowed
) changes. This optimization can be helpful in certain scenarios to improve performance.
HOOK - useEffect
useEffect
is a hook provided by React that allows you to perform side effects in function components. Side effects can include things like data fetching, subscriptions, or manually changing the DOM.It takes two arguments: a function and an optional dependency array.
The function passed to
useEffect
will run after every render by default. However, you can specify dependencies in the dependency array so that the effect will only run if any of those dependencies have changed.If you provide an empty dependency array, the effect will only run once, similar to
componentDidMount
in class components.If you return a cleanup function from the function passed to
useEffect
, it will be executed before the effect runs again or when the component unmounts.Note ,
In this basically i want to say that the first default call will go for setPassword so that password generate and visible in input box after that when any change will occur in the dependencies that we have provided then this useEffect will call otherwise not this save us to call for infinite times .
If we not use useEffect and directly call only passwordGenerator()
then it will call for infinte times.
In summary, useEffect
is for managing side effects, while useCallback
is for optimizing the performance of functions by memoizing them.
Handle copy
handleCopy
is a simple function that copies the generated password to the clipboard when invoked. It uses the navigator.clipboard.writeText()
method to write the password
to the clipboard.
Another code without useCallback
import { useEffect, useState } from 'react';
function App() {
const [length, setLength] = useState(8);
const [numberAllowed, setNumberAllowed] = useState(false);
const [characterAllowed, setCharacterAllowed] = useState(false);
const [password, setPassword] = useState('');
useEffect(() => {
let pass = '';
let str = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';
if (numberAllowed) {
str += '0123456789';
}
if (characterAllowed) {
str += '~!@#$%^&*()_±={}|[]:';
}
for (let i = 1; i <= length; i++) {
let char = Math.floor(Math.random() * str.length);
pass += str.charAt(char);
}
setPassword(pass);
}, [length, numberAllowed, characterAllowed]);
const handleCopy = () => {
navigator.clipboard.writeText(password);
};
return (
<>
<div className="flex justify-center items-center min-h-screen bg-gray-100">
<div className="w-2/4 p-6 bg-white rounded-lg shadow-md">
<h1 className="text-3xl font-bold mb-4 text-center">Password Generator</h1>
<div className="flex mb-4">
<input
type="text"
value={password}
className="border rounded px-4 py-2 w-full mr-2"
placeholder="Password"
readOnly
/>
<button
className="bg-blue-500 text-white px-4 py-2 rounded"
onClick={handleCopy}
>
Copy
</button>
</div>
<div className="mb-4">
<input
type="range"
value={length}
min={6}
max={100}
onChange={(e) => setLength(e.target.value)}
className="w-full"
/>
<label className="block">Length: {length}</label>
<input
type="checkbox"
defaultChecked={numberAllowed}
onChange={() => setNumberAllowed((prev)=>!prev)}
className="mr-2"
/>
<label className="mr-4">Numbers</label>
<input
type="checkbox"
defaultChecked={characterAllowed}
onChange={() => setCharacterAllowed((prev)=>!prev)}
className="mr-2"
/>
<label>Characters</label>
</div>
</div>
</div>
</>
);
}
export default App;
As here both hooks are doing same thing to save again and again from re-rendering so we used only useEffect.