如何在使用CompositionLocal修改父数据时触发重新组合



当我使用CompositionLocal时,我已经从父级获得了数据并对其进行了修改,但我发现它不会触发子级重组。

我已经成功地更改了数据,这可以证明,当我在子可组合中添加一个额外的状态,然后更改它以触发重新组合时,我可以获得新的数据。

有人能帮我吗?

追加

代码如下


data class GlobalState(var count: Int = 0)
val LocalAppState = compositionLocalOf { GlobalState() }
@Composable
fun App() {
CompositionLocalProvider(LocalAppState provides GlobalState()) {
CountPage(globalState = LocalAppState.current)
}
}
@Composable
fun CountPage(globalState: GlobalState) {
// use it request recomposition worked
//    val recomposeScope = currentRecomposeScope
BoxWithConstraints(
contentAlignment = Alignment.Center,
modifier = Modifier
.fillMaxSize()
.clickable {
globalState.count++
//                recomposeScope.invalidate()
}) {
Text("count ${globalState.count}")
}
}

我发现了一个变通方法是使用currentRecomposable强制重组,也许有更好的方法,请告诉我。

这里的组合local是转移注意力。由于CCD_ 2是不可观测的,因此组合物没有被通知其改变。最简单的更改是将GlobalState的定义修改为

class GlobalState(count: Int) {
var count by mutableStateOf(count)
}

这将自动通知撰写count的值已更改。

我不知道您为什么以这种方式使用compositionLocalOf

使用状态提升模式,您可以在组合中使用两个参数:

  • value: T:要显示的当前值
  • onValueChange: (T) -> Unit:请求值更改的事件,其中T是建议的新值

在您的情况下:

data class GlobalState(var count: Int = 0)
@Composable
fun App() {
var counter by remember { mutableStateOf(GlobalState(0)) }
CountPage(
globalState = counter,
onUpdateCount = {
counter = counter.copy(count = counter.count +1)
}
)
}
@Composable
fun CountPage(globalState: GlobalState, onUpdateCount: () -> Unit) {

BoxWithConstraints(
contentAlignment = Alignment.Center,
modifier = Modifier
.fillMaxSize()
.clickable (
onClick = onUpdateCount
)) {
Text("count ${globalState.count}")
}
}

您可以将数据声明为MutableState,并分别提供getter和setter,或者直接提供MutableState对象。

internal val LocalTest = compositionLocalOf<Boolean> { error("lalalalalala") }
internal val LocalSetTest = compositionLocalOf<(Boolean) -> Unit> { error("lalalalalala") }
@Composable
fun TestProvider(content: @Composable() () -> Unit) {
val (test, setTest) = remember { mutableStateOf(false) }
CompositionLocalProvider(
LocalTest provides test,
LocalSetTest provides setTest,
) {
content()
}
}

在子组件内部,您可以执行以下操作:

@Composable
fun Child() {
val test = LocalTest.current
val setTest = LocalSetTest.current
Column {
Button(onClick = { setTest(!test) }) {
Text(test.toString())
}
}
}

相关内容

  • 没有找到相关文章

最新更新