0

当我使用 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用来强制重组,也许有更好的方法,请告诉我。

4

3 回答 3

1

我不确定您为什么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}")
    }
}
于 2021-05-18T18:08:29.313 回答
0

当地的作文在这里是一条红鲱鱼。由于GlobalScope不是可观察的组合,因此不会通知它已更改。最简单的改变就是修改to的定义GlobalState

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

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

于 2021-05-19T20:52:58.277 回答
0

您可以将数据声明为 aMutableState并分别提供 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())
    }
  }
}
于 2021-11-25T12:17:55.143 回答