I am new to ReactJs, my understanding of custom hooks is that they are used for separating logic into a function. In many of the custom hook examples I have seen uses some built-in hook (mostly useState and useEffect). Is it mandatory to use built-in hooks ?
If for example, I have a code like this (Fiddle)
export default function App() {
const [data, setData] = useState();
const isEven = checkEven(data);
const isAboveHundred = checkIsAboveHundred(data);
const isPrime = checkEven(data);
return (
<>
<label>
Enter number:
<input
type="number"
value={data}
onChange={(e) => setData(e.target.value)}
/>
</label>
<div> Number is {isEven ? 'even' : 'odd'}</div>
<div> Number is {isAboveHundred ? 'above' : 'less'} than 100</div>
<div> Number is {isPrime ? 'prime' : 'not prime'}</div>
</>
);
}
// helper functions
function checkEven(num) {
const isEven = num % 2 === 0;
return isEven;
}
function checkIsAboveHundred(num) {
const isAboveHundred = num > 100;
return isAboveHundred;
}
function checkPrime(num) {
for (let i = 2, s = Math.sqrt(num); i <= s; i++) {
if (num % i === 0) return false;
}
return num > 1;
}
and if I am asked to change these helper functions to custom hooks, is it fine to just rename them to useCheckEven, useCheckIsAboveHundred, useCheckPrime and keep the function body as it is.
Like this
// custom hooks
function useCheckEven(num) {
const isEven = num % 2 === 0;
return isEven;
}
function useCheckIsAboveHundred(num) {
const isAboveHundred = num > 100;
return isAboveHundred;
}
function useCheckPrime (num) {
for (let i = 2, s = Math.sqrt(num); i <= s; i++) {
if (num % i === 0) return false;
}
return num > 1;
}
Is it mandatory to wrap them in a useEffect (or useState) like below ? (Fiddle)
// custom hooks
function useCheckEven(num) {
const [isEven, setIsEven] = useState(false);
useEffect(() => {
const newValue = num % 2 === 0;
setIsEven(newValue);
}, [num]);
return isEven;
}
function useCheckIsAboveHundred(num) {
const [isAboveHundred, setIsAboveHundred] = useState(false);
useEffect(() => {
const newValue = num > 100;
setIsAboveHundred(newValue);
}, [num]);
return isAboveHundred;
}
function useCheckPrime(num) {
const [isPrime, setIsPrime] = useState(false);
// helper function
// taken from /a/40200212/26420821
// not sure if this should be in useCallback
function checkPrime(num) {
var sqrtnum = Math.floor(Math.sqrt(num));
var prime = num != 1;
for (var i = 2; i < sqrtnum + 1; i++) {
// sqrtnum+1
if (num % i == 0) {
prime = false;
break;
}
}
return prime;
}
useEffect(() => {
const newValue = checkPrime(num);
setIsPrime(newValue);
}, [num]);
return isPrime;
}
I tried both ways and they seem to be working. I am not sure which way is right. Please guide
2
While hooks are used for separating logic into a function, they are specifically used for separating stateful logic into a separate function. If you function does not control any state or call any other hooks, it does not need to be a hook.
Within a custom hook, you can see either built-in hooks being called or custom hooks. Neither is specifically required.
Before hooks, any state aware code had to exist within a Component. Hooks allows you to reoganize stateful logic into a seperate function.
Since useCheckEven(num), useCheckIsAboveHundred(num), and useCheckPrime(num) above do not track any state objects, they do not need to be a hook. It would be easier to call them and straight JS functions.