Trying new architecture paradigm where presenter creates immutable state(model) stream and view just renders it.
Can't understand how to handle situations where we need to make some event for the one time only. There are couple examples.
1) Notes app. We have editText
and saveButton
. User clicks saveButton
, some processing happens and editText should be cleared. Could you guys please describe what will be in our ViewState
here and approximate logic flow?
Questions and pitfalls I see now:
- We subscribe to
editText.textChanges()
in presenter. If we will havetext
in ourViewState
and render it each render call then we will fall into recursion because it will emit new textChange and will update state and render again. - Do we need
text
inViewState
to restore it on orientation text or process kill/restore, looks like it works out of box here. But imaginerecyclerView
s scroll position. We definitely need to save it to restore. We can't restore it on each render call cause it looks weird, isn't it? - If we consider such logic as side effect and will call
.doOnNext{ view.clearText() }
it makes sense, but do we have reference to view in canonical MVI implementation? Mosby doesn't have it as I see. - It makes sense but there is possibility of view being dead in the moment of
doOnNext
call. MVI should help us with this but only if it's the part ofViewState
, right?
2) Github app. First screen(Org): orgEditText
, okButton
, progressBar
. Second screen (Repos): recyclerView
. When user enters organization into orgEditText
and clicks okButton
app should make request to API and on success navigate to Repos screen on success or show toast on failure. Again could you please describe ViewState
for Org screen and what logic should look like?
Questions and pitfalls I see now:
- We should show
progressBar
and disableokButton
while loading. We should have like loading/content/error sealed class(lets call itContentState
) and have its instance in ourViewState
. View knows how to renderContentState.loading
and showsprogressBar
and disablesokButton
. Am I right? - How to handle navigation then? The same questions as 1.3 and 1.4.
- I've seen opinions that navigation should be considered as side effect, but again 1.4.
- Toast - is there something in state or we consider this as side effect? Same problems.
Google suggests SingleLiveEvent
solution, but it looks weird and then there should be as much LiveData<SingleLiveEvent>
streams as we have such things, not really a single source of truth.
Others suggest new intent generated from render func which is better but there is a possibility that some async operations will change state again and we'll get second Toast while first is showing and so on.