Update State outside the composable function. (Jetpack compose)

Viewed 3870

I am trying to implement redux with Jetpack compose. The scenario looks like this:

I have a list view where I need to show data, in composable function.

    @Composable
    fun CreateListView(text: String) {
     val listdata = state { store.state }

        LazyColumn {
         //some listview code here
        }
    }

above, I want to use the data that I got from the redux store. but the store. The subscription method is standalone, and outside the composable. where, though I am able to update the state through new data, but the changes are not reflecting back to composable listview:

    // activity page outside composable
    private fun storeSubscription(){
        viewModel.storeSubscription = store.subscribe {

            when (store.state) {
                store.state = // list data from some source
            }
        }
    }

Is it possible to update the composable, like above, from outside the function, and without sending any parameter? Since the redux store is a global one, so it should work I think.

3 Answers

You can use MutableLiveData outside of composable function. Use observeAsState() in composable to recompose when data changes.

private val myLive = MutableLiveData<String>()

fun nonComposableScope(){
  myLive.postValue("hello")
}

@Composable
fun MyScreen(textLive:LiveData<String>){
  val text: String? by textLive.observeAsState()
  // use text here
}

Try something like,

@Composable
fun <T> Store<T>.asState(): State<T> {
   val result = remember { mutableStateOf(store.state) }
   DisposableEffect {
       val unsubscribe = store.subscribe {
           result.value = store.state
       }
       onDispose { unsubscribe() }
   }
   return result
}

@Composable
fun CreateListView(text: String) {
    val listdata by store.asState()

    LazyColumn {
     //some listview code here
    }
}

The exact code might differ as I don't know what redux implementation you are using.

This creates an observable state object that will be updated whenever the lambda passed to subscribe is called. Also, it will automatically unsubscribe when CreateListView is no longer part of the composition.

You have to follow the state hosting pattern From Android Domcumentaiton

Key Term: State hoisting is a pattern of moving state up the tree to make a component stateless.

When applied to composables, this often means introducing two parameters to the composable:

value: T: the current value to display. onValueChange: (T) -> Unit: an event that requests the value to change where T is the proposed new value.

So in your case you will save the state in the upper Composable that needs to access it, and pass the value of the state and a lambda function to change it to the other Composable, you can learn more from the Official Documentation.

Related