If you don't wrap the child component with "React.memo", every time the parent renders the child will render regardless of prop equality, even with memoized props/callbacks.
Adding useCallback for functions only does something useful if you also React.Memo those children. So while this is a very important optimization, it's not one you need to apply to everything.
It only exists/is done to give you a stable reference so you can avoid triggering downstream dependencies (hook arrays and React.memo'd components)
One reason useCallback exists is because useMemo, too, allocates a function on every render- even if it doesn't recompute the underlying value by actually calling the function. So if you're going to be allocating a function anyway, there's no point (performance-wise) to allocating a function that creates a function. You can just cut out the middle-man
The virtual DOM is a tree, and if roughly balanced, the path that needs to be updated is of size log(N) compared to the full tree of size N that will be updated by default.
In practice, it's the difference between a stuttering app that lags at every keypress in an input field, and something usable.