the code inside the callback provides valuable documentation as to why the view update is needed

I like that. It's probably one of the main reasons why people found setState with an anonymous callback easier to comprehend!

Leaving it empty is now a code-smell to me

Yeah, that irks me out too.

There have been cases where I felt it was probably okay to leave it empty, but those are few and far between.

GitHub-flavored Markdown & a sane subset of HTML is supported.