Viewstate if you don't need to reference it in client side script. A Hidden field if you do.
Also consider that if the data is sensitive, the Viewstate is encrypted by default, whereas the hidden field, by default, stores it as plain text visible to anyone who knows how to view source.
Edit
Per @Andrew Hare's note on his own answer, I'm editing this. It's an important enough distinction to note. I'd hate for someone to think they were "safe" using the Viewstate based on my oversight.
The Viewstate is NOT encrypted by default, it's stored as Base-64 encoding. It can be decoded fairly easily, so using the Viewstate because it's encrypted by default is not valid. It's better than plain text, but not to anyone with the ability to google "decrypt Viewstate" or "decode Viewstate".
So don't rely on the Viewstate to protect your hidden information in client side code.
An article here tells how to encrypt it properly. (but also warns about performance issues).