EDIT (22 June 2020): as this question has some renewed interest, I realise there may be a few points of confusion. So I would like to highlight: the example in the question
For your scenario (where you cannot keep creating new callbacks and passing them to your 3rd party library), you can use useRef to keep a mutable object with the current state. Like so:
function Card(title) {
const [count, setCount] = React.useState(0)
const [callbackSetup, setCallbackSetup] = React.useState(false)
const stateRef = useRef();
// make stateRef always have the current count
// your "fixed" callbacks can refer to this object whenever
// they need the current value. Note: the callbacks will not
// be reactive - they will not re-run the instant state changes,
// but they *will* see the current value whenever they do run
stateRef.current = count;
function setupConsoleCallback(callback) {
console.log("Setting up callback")
setInterval(callback, 3000)
}
function clickHandler() {
setCount(count+1);
if (!callbackSetup) {
setupConsoleCallback(() => {console.log(`Count is: ${stateRef.current}`)})
setCallbackSetup(true)
}
}
return (
Active count {count}
);
}
Your callback can refer to the mutable object to "read" the current state. It will capture the mutable object in its closure, and every render the mutable object will be updated with the current state value.