redux 更新可组合函数外部的状态,(Jetpack组合)

nzkunb0c  于 2022-11-12  发布在  其他
关注(0)|答案(4)|浏览(165)

我正在尝试使用Jetpack compose实现redux。场景如下所示:
我有一个列表视图,我需要在其中显示数据,在组合函数。

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

        LazyColumn {
         //some listview code here
        }
    }

在上面,我想使用从redux存储中获得的数据。但是,存储。订阅方法是独立的,并且在可组合的。其中,虽然我能够通过新数据更新状态,但是这些更改不会反映回可组合的列表视图:

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

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

有没有可能像上面一样,从函数外部更新可组合的,而不发送任何参数?因为redux存储是一个全局存储,所以我认为它应该工作。

ou6hu8tu

ou6hu8tu1#

您可以在可组合函数之外使用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
}
webghufk

webghufk2#

你可以这样说,

@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不再是组合的一部分时,它将自动取消订阅。

jjjwad0x

jjjwad0x3#

您必须遵循状态托管模式From Android Domcumentaiton
关键词:状态提升是一种将状态向上移动以使组件无状态的模式。
当应用于可组合对象时,这通常意味着向可组合对象引入两个参数:
value:T:要显示的当前值。onValueChange:(T)-〉单位:请求更改值的事件,其中T是建议的新值。
所以在你的例子中,你将把状态保存在需要访问它的上层Composable中,并传递状态的值和一个lambda函数,以将其更改为另一个Composable,你可以从官方文档中了解更多信息。

wlp8pajw

wlp8pajw4#

您可以像这样简单地使用lambda:

(An示例来自我正在开发的应用程序。)

@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun RumbleSearchResult(rumbleSearchResult: RumbleSearchResult, onClick: () -> Unit) {
    ListItem(
        headlineText = {
            rumbleSearchResult.title?.let { title ->
                Text(title)
            }
        },

        supportingText = {
            rumbleSearchResult.channel.let { creator ->
                val text = when {
                    rumbleSearchResult.views > 0 -> {
                        "${creator.name}, ${rumbleSearchResult.views} views"
                    }

                    else -> {
                        creator.name ?: ""
                    }
                }

                Row {
                    Text(text)

                    if (creator.isVerified) {
                        Icon(
                            painter = painterResource(R.drawable.ic_baseline_verified_24),
                            tint = Color.Cyan,
                            contentDescription = stringResource(id = R.string.mainActivity_verified_content_description)
                        )
                    }
                }
            }
        },

        leadingContent = {
            AsyncImage(
                rumbleSearchResult.thumbnailSrc,
                contentDescription = null,
                modifier = Modifier.size(100.dp, 100.dp)
            )
        },

        modifier = Modifier.clickable {
            onClick.invoke()
        }
    )
    Divider()
}

主要组成:

LazyColumn {
    items(viewModel.searchResults) {
        RumbleSearchResult(rumbleSearchResult = it) {
            openDialog = true
        }
    }
}

相关问题