Does the order of useCallback function declaration matters? For example:
Functions declared in this order:
const aboveFunction = useCallback(()=>{ logCount() },[logCount])
const logCount = useCallback(()=>{ console.log(count) },[count])
const belowFunction = useCallback(()=>{ logCount() },[logCount])
Notice both aboveFunction and belowFunction refers to the same logCount.
After we call setCount(2) ,
aboveFunction() -> logCount() -> count // 0, wheres
belowFunction() -> logCount() -> count // 2
https://codesandbox.io/s/react-hooks-counter-demo-forked-7mofy?file=/src/index.js
/**
Click increment button until count is 2, then click
Above and Below button and check console log
* Even though the count value is > 0, aboveIncrement console.log(count) still gives 0
*/
import React, { useState, useCallback } from "react";
import ReactDOM from "react-dom";
import "./styles.css";
function App() {
const [count, setCount] = useState(0);
/** Assuming all the functions below do some intensive stuffs to justify useCallback */
const aboveFunction = useCallback(() => {
// ...do other intensive stuff
logCount("Above count:"); // Above count: 0
}, [logCount]);
const logCount = useCallback(
(str) => {
// ...do other intensive stuff
console.log(str, count);
},
[count]
);
const belowFunction = useCallback(() => {
// ...do other intensive stuff
logCount("Below count:"); // Above count: 2
}, [logCount]);
return (
<div className="App">
<h1>
Click increment button until count is 2, then click Above/ Below button
and see console log
</h1>
<h2>You clicked {count} times!</h2>
<div
style={{
display: "flex",
alignItems: "center",
flexDirection: "column"
}}
>
<button style={{ margin: 10 }} onClick={aboveFunction}>
Above Increment Function
</button>
<button style={{ margin: 10 }} onClick={() => setCount(count + 1)}>
Increment
</button>
<button style={{ margin: 10 }} onClick={belowFunction}>
Below Increment Function
</button>
</div>
</div>
);
}
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
It is apparent that the order of useCallback declaration is important in order for the code to work. However, if we write it this way https://codesandbox.io/s/react-hooks-counter-demo-forked-7mofy?file=/src/index1.js
let logCount;
const aboveFunction = useCallback(() => {
logCount("Above count:"); // Above count: 0
}, [logCount]);
logCount = useCallback((str) => {
console.log(str, count);
}, [count]
);
const belowFunction = useCallback(() => {
logCount("Below count:"); // Above count: 2
}, [logCount]);
aboveFunction still gives stale count value. Is there any rule-of-hooks that I'm missing?
Yes a fix here is to apply eslint no-use-before-define. But I wanna understand the reason why .. isn’t functions get hoisted up in JavaScript and the order in which it is declared doesn’t matter?
Is there any rule-of-hooks that I'm missing?
You are not missing rule-of-hooks but, you are missing no-use-before-define rule.
You have to use the logCount function above the aboveFunction.
In this attached image as well

you can see, it's showing a warning for function declaration.
Maybe you can add es-lint in your project and make sure you add this plugin & no-use-before-define as well so that it will show you these types of warning in vs code.
Hope this helps!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With