-
Notifications
You must be signed in to change notification settings - Fork 0
MvRx
Devrath edited this page Apr 10, 2024
·
10 revisions
- Mavericks is a
MVI-framework
/** State classes contain all of the data you need to render a screen. */
data class CounterState(val count: Int = 0) : MavericksState
/** ViewModels are where all of your business logic lives. It has a simple lifecycle and is easy to test. */
class CounterViewModel(initialState: CounterState) : MavericksViewModel<CounterState>(initialState) {
fun incrementCount() = setState { copy(count = count + 1) }
}
/**
* Fragments in Mavericks are simple and rarely do more than bind your state to views.
* Mavericks works well with Fragments but you can use it with whatever view architecture you use.
*/
class CounterFragment : Fragment(R.layout.counter_fragment), MavericksView {
private val viewModel: CounterViewModel by fragmentViewModel()
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
counterText.setOnClickListener {
viewModel.incrementCount()
}
}
override fun invalidate() = withState(viewModel) { state ->
counterText.text = "Count: ${state.count}"
}
}Mastering Mavericks only requires using three classes
- This is the first step in creating a Screen by modeling it as a function of state.
- The Mavericks state doesn't do anything but signal the intention of your class to be used as a state.
- Ensuring the state class is a
data class. - Uses only immutable properties.
- All the properties have a default value so that it can be immediately loaded.
data class UserState(
val score: Int = 0,
val previousHighScore: Int = 150,
val livesLeft: Int = 99,
) : MavericksState- You can create
derived properties, Thederived propertiesare the properties inside the body of your state class.
data class UserState(
val score: Int = 0,
val previousHighScore: Int = 150,
val livesLeft: Int = 99,
) : MavericksState {
// Properties inside the body of your state class are "derived".
val pointsUntilHighScore = (previousHighScore - score).coerceAtLeast(0)
val isHighScore = score >= previousHighScore
}- Placing logic as a derived property like
pointsUntilHighScoreorisHighScoremeans that, You can subscribe to changes to just these derived properties, It will never be out of sync with the underlying state.
- It is responsible for updating the state.
- It is responsible for exposing the stream of states that other classes subscribe to.
- It is similar to
JetpackViewModelscondition being generic on aMavericksStateclass. - Updating the state involves, From within a viewModel, you call
setState { copy(yourProp = newValue) }. -
copycomes from the state class being adata class. - The lambda is not executed synchronously. It is put on a queue and run on a background thread.
- Handling asynchronous operations with ease was one of the primary goals of Mavericks.
- It is where you render your state class to the screen.
- Most of the time, It will be a fragment but it doesn't have to be.
- By implementing the
MavericksView, We get access to-
MavericksViewModelusing view model delegates. - We will automatically be able to subscribe from changes and call
invalidate(). -
Overridingtheinvalidate()function so that whenever the state changes the view is notified here.
-