The official documentation for the loop hasn’t changed:
It is always recommended to have
if ( have_posts() ). You want to show some nice content if there are no posts.
There are cases in which the developer will choose not to use it, such as single.php or page.php – the template file will never be loaded if the query returns no posts, so no need for an error catch.
You can read a discussion on why the
if while logic is needed at https://wordpress.stackexchange.com/questions/117219/why-should-i-put-ifhave-posts-is-whilehave-posts-not-enough
Hope this helps,