airbnb / mavericks

Mavericks: Android on Autopilot
https://airbnb.io/mavericks/
Apache License 2.0
5.85k stars 498 forks source link

setState run multiple times #615

Closed SJJupiter closed 2 years ago

SJJupiter commented 2 years ago

I tried the demo in mavericks 2.0's doc, but found that block in setState() run multiple times, is that normal?

data class CounterState(val count: Int = 0) : MavericksState

class MainViewModel(initialState: CounterState) : MavericksViewModel<CounterState>(initialState) {
    fun incrementCount() = setState {
        Log.d("MvRx", "setState: ${System.currentTimeMillis()}")
        copy(count = count + 1)
    }
}

class SecondFragment: Fragment(R.layout.fragment_layout), MavericksView {
    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        initView()
    }

    private fun initView() {
        testText2.setOnClickListener {
            mainViewModel.incrementCount()
        }
    }

    override fun invalidate() { 
        Log.d("MvRx", "invalidate is  called")
    }
}
2022-02-20 18:40:55.355 11999-11999/com.example.mvrxtwotest D/MvRx: setState: 1645353655355
2022-02-20 18:40:55.356 11999-12032/com.example.mvrxtwotest D/MvRx: setState: 1645353655356
2022-02-20 18:40:55.356 11999-12032/com.example.mvrxtwotest D/MvRx: setState: 1645353655356
2022-02-20 18:40:55.357 11999-11999/com.example.mvrxtwotest D/MvRx: invalidate is  called
gpeal commented 2 years ago

Yes, this is expected for debug builds. It is part of Maverick's checks to make sure that your reducer is pure. https://airbnb.io/mavericks/#/debug-checks?id=debug-checks