I recently shared this tweet, which generated some interesting discussion.
As Paul mentions, the first method may be totally fine for you and it's really about ref equality, not cost of creating a new function. If you're passing toggle down to child components then you may want ref equality to avoid extra renders.
Whichever way you go though, you'll want to use a function argument for useState to avoid this bug.
And finally, this can also be implemented with useReducer. As always, the best way to learn is to share your solution publicly and wait for people to tell you how it can be done better :)
Thanks for sharing, my hook knowledge is pretty shallow. I'm gonna have to read this more carefully when my brain is less tired. I recently tried making a custom hook to detect mouse double-clicks... basically I randomly tried different things with useState, useRef and useCallback until I got it to work how I wanted 🙄