在可组合函数之外更新状态。 (喷气背包组合)
Update State outside the composable function. (Jetpack compose)
我正在尝试使用 Jetpack compose 实现 redux。场景如下所示:
我有一个列表视图,需要在可组合函数中显示数据。
@Composable
fun CreateListView(text: String) {
val listdata = state { store.state }
LazyColumn {
//some listview code here
}
}
以上,我想使用从 redux store 获取的数据。但商店。订阅方法是独立的,在可组合项之外。其中,虽然我能够通过新数据更新状态,但更改不会反映回可组合列表视图:
// activity page outside composable
private fun storeSubscription(){
viewModel.storeSubscription = store.subscribe {
when (store.state) {
store.state = // list data from some source
}
}
}
是否可以像上面那样从函数外部更新可组合项,而不发送任何参数?由于 redux 商店是全球商店,所以我认为它应该可以工作。
您必须遵循状态托管模式
来自 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.
所以在你的情况下,你会将状态保存在需要访问它的上层Composable中,并通过状态的值和一个lambda函数将其更改为另一个Composable,你可以从官方了解更多文档。
尝试类似的东西,
@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
}
}
确切的代码可能有所不同,因为我不知道您使用的是什么 redux 实现。
这将创建一个可观察的状态对象,只要传递给 subscribe
的 lambda 被调用,该对象就会更新。此外,当 CreateListView
不再是作品的一部分时,它将自动取消订阅。
您可以在可组合函数之外使用 MutableLiveData。在可组合项中使用 observeAsState() 以在数据更改时重新组合。
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
}
我正在尝试使用 Jetpack compose 实现 redux。场景如下所示:
我有一个列表视图,需要在可组合函数中显示数据。
@Composable
fun CreateListView(text: String) {
val listdata = state { store.state }
LazyColumn {
//some listview code here
}
}
以上,我想使用从 redux store 获取的数据。但商店。订阅方法是独立的,在可组合项之外。其中,虽然我能够通过新数据更新状态,但更改不会反映回可组合列表视图:
// activity page outside composable
private fun storeSubscription(){
viewModel.storeSubscription = store.subscribe {
when (store.state) {
store.state = // list data from some source
}
}
}
是否可以像上面那样从函数外部更新可组合项,而不发送任何参数?由于 redux 商店是全球商店,所以我认为它应该可以工作。
您必须遵循状态托管模式 来自 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.
所以在你的情况下,你会将状态保存在需要访问它的上层Composable中,并通过状态的值和一个lambda函数将其更改为另一个Composable,你可以从官方了解更多文档。
尝试类似的东西,
@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
}
}
确切的代码可能有所不同,因为我不知道您使用的是什么 redux 实现。
这将创建一个可观察的状态对象,只要传递给 subscribe
的 lambda 被调用,该对象就会更新。此外,当 CreateListView
不再是作品的一部分时,它将自动取消订阅。
您可以在可组合函数之外使用 MutableLiveData。在可组合项中使用 observeAsState() 以在数据更改时重新组合。
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
}