The difference between the two is that
wp_reset_query()– ensure that the main query has been reset to the original main querywp_reset_postdata()– ensures that the global$posthas been restored to the current post in the main query.
Indeed, looking at the source you’ll see that the wp_reset_query() calls wp_reset_postdata(). The only difference between the two then is this line:
$GLOBALS['wp_query'] = $GLOBALS['wp_the_query'];
(in wp_reset_query()). So wp_reset_query() is only necessary should those two globals differ, and that only happens if query_posts() has been used somewhere.
When should I use them?
Simply put:
wp_reset_postdata()– immediately after every customWP_Query()wp_reset_query()– immediately after every loop usingquery_posts()
Should I use wp_reset_query
Well, yes, but it’s only needed after using query_posts(). As you’ve pointed out you should never use query_posts(). So if you aren’t ever using query_posts() then it’s not necessary to call wp_reset_query() (instead of wp_reset_postdata().
In short, it’s not that you shouldn’t use wp_reset_query() instead of wp_reset_postdata(), it’s that you shouldn’t ever need to!