Let's start with the fact that they share the same goal: reducing the number of unnecessary component renders, which lowers CPU usage and, in theory, saves you from potential performance problems. This matters especially if the user opens your website on a phone or your app runs on Ionic, React Native, etc.
When to use useMemo
Put simply, it memoizes the result of a computation. Imagine you have a trading platform that receives real-time price data for various assets. On the frontend you need to recalculate these values and, based on them, update various charts, tables, the user's portfolio, and so on. But not every update requires a re-render. For example, if an asset's price hasn't changed, there is no need to redraw its chart. Мемоізація(useMemo) lets you cache the value and update the component only when its input parameters have changed.
When to use useCallback
When a component renders, the functions declared inside it are recreated as well. In theory, this can affect performance, especially when using super-abstract frameworks such as Ionic. useCallback lets you return the same function instance between renders until its dependencies change. This way it memoizes the function and helps us avoid unnecessary re-creations.
In an interview, it's good form to say that any performance optimization should be based on current or potential problems, and the worst thing you can do is spend time optimizing where it makes no sense.