useMemo caches the result of calling your function.
useCallback caches the function itself.
In fact, you can think of
useCallback as applying
useMemo to a function, i.e., memoizing a function with useMemo. In fact in the memoizing a function section just linked to, they write,
The only benefit to useCallback is that it lets you avoid writing an extra nested function inside. It doesn’t do anything else.
It's not harmful to use it everywhere, which has led to some embracing the mantra of "memoize everything",
There is no significant harm to doing that either, so some teams choose to not think about individual cases, and memoize as much as possible. The downside is that code becomes less readable.
It does indeed result in less readable code. Noisy looking code. Also, it's not useful (while not harmful) in many situations.
... not all memoization is effective: a single value that’s “always new” is enough to break memoization for an entire component.
Note that useCallback does not prevent creating the function. You’re always creating a function (and that’s fine!), but React ignores it and gives you back a cached function if nothing changed.
The above youtube link covers research they are working on, codenamed "React forget", with the goal or removing memoization