You're on the right track not duplicating json decoding and encoding when they're part of larger things. You can do the same with init, too.
Having state in components comes up a lot as a question in elm, I wrote about my take on how this should ideally work:
In other words, the real app is a set of messages that a concentrated, hidden state. If components need small, non-serialized state such as whether a menu is open or a moveable object has handles shown, then local state is appropriate (and shouldn't be serialized). If the information has more reach and needs save and restore, then store it in the State, and pass that state down to the components, allowing them to bubble up messages to change it.
The important part is that you're decoupling the app's state from the shape of the UI and enabling code to be written about it without coupling that code to the views; instead, the views and the app's other code cooperate over some data you define to get the best from each. In this model, you'll move the types and codecs to a tier above State, where they'll be imports to everything downstream, and not isolate the types themselves in views. My experience suggests that encapsulation isn't as important as it is elsewhere when you don't have to worry about mutation.
If you're having trouble sorting out how to handle the initial Cmd result from init, try using:
Ideally, there won't be duplication between your decoder and init ... worst case, you'd decode first, then copy the data you needed or wanted afterward, providing defaults in the bad decode case.