I'd say it's the officially suggested method in the sense that we describe it in our dynamic UI article, for the cases when you really need it (in the article itself, there's also a small demo app using this mechanism):
The condition can also use output values; they work in the same way (output.foo gives you the value of the output foo). If you have a situation where you wish you could use an R expression as your condition argument, you can create a reactive expression in the server function and assign it to a new output, then refer to that output in your condition expression. If you do this, make sure to also set outputOptions(output, [newOutputName], suspendWhenHidden = FALSE). (This is necessary because Shiny normally doesn’t send values to the browser for outputs that are hidden or not present in the UI. In this case, however, the browser does need to know the most up-to-date output value in order to correctly evaluate the condition of the contitionalPanel function - suspendWhenHidden = FALSE ensures this will happen.)
I think this would still be the way to implement this functionality, but I guess we could create some syntactic sugar to "hide" the inelegant mechanism, instead of exposing it. But since it's just one line anyway, I don't think it's a high priority trade-off. If you were thinking of an alternative that didn't use the output list and the "hack," that would mean introducing a new list (in addition to input and output) that would also travel between the server and the client (and also make the mental model and the reactlog potentially more complicated). Given that there is (so far, at least) only this use case, I don't think we're likely to do it. But this is mostly my opinion, I don't recall ever discussing this with the team.