Ok, so this question isn't actually about useEffect but about SetStateAction.
Ie:
setState(tick + 1);
vs
setState(tick => tick + 1);
The answer has to do with concurrency. What if you call setState(tick + 1), twice in the same render? You will update it to the same value, instead of incrementing twice like you would expect. If you pass a function to setState you will get as the first argument the latest value, instead of the value that was bound to your render.
Edit:
One issue that your code has:
function IntervalHookCounter() {
const [count,setCount] = useState(0)
useEffect(()=>{
const interval = setInterval(tick,1000)
},[])
const tick = ()=>{
//...
}
Is that you're not managing your dependencies accurately.
Your useEffect has a depdency on tick, and tick has dependency on count. Except in the 2nd example it doesn't have that dependency on count.
If you install a linting tool you will see warnings that you're missing dependencies in your code. And in the first example it's actually a problem. If the first example, adding tick as a dependency will cause the code to behave in unintended ways, especially since you're not cleaning up your setInterval in the useEffect.