gpt4 book ai didi

kotlin - kotlin-react useEffect中如何订阅StateFlow

转载 作者:行者123 更新时间:2023-12-02 12:21:14 25 4
gpt4 key购买 nike

我正在尝试使用 kotlin 1.4-M2 使用 functionalComponent 为 kotlin-react 创建一个小的反例。该示例应使用 kotlinx.coroutines.flow。我正在努力从 react useEffect Hook 中的商店收集值。

商店:

object CounterModel { // Modified sample from kotlin StateFlow doc
private val _counter = MutableStateFlow(0) // private mutable state flow
val counter: StateFlow<Int> get() = _counter // publicly exposed as read-only state flow

fun inc() { _counter.value++ }
}

组件:

val counter = functionalComponent<RProps> {
val (counterState, setCounter) = useState(CounterModel.counter.value)

useEffect(listOf()) {
// This does not work
GlobalScope.launch { CounterModel.counter.collect { setCounter(it) } }
}

div {
h1 {
+"Counter: $counterState"
}
button {
attrs.onClickFunction = { CounterModel.inc() }
}
}
}

当我直接调用 CounterModel.counter.collect { setCounter(it) } 时,它会提示 Suspend function 'collect' should be called only from a coroutine or another suspend function.

你将如何实现这个 useEffect 钩子(Hook)?

一旦订阅生效,您将如何取消订阅(使用 useEffectWithCleanup 而不是 useEffect)?

最佳答案

终于找到解决办法了。我们可以使用 onEach 为每个新值执行操作,然后使用 launchIn 进行“订阅”。这将返回一个可以取消清理的作业:

object CounterStore {
private val _counter = MutableStateFlow(0)
val counter: StateFlow<Int> get() = _counter

fun inc() { _counter.value++ }
}

val welcome = functionalComponent<RProps> {
val (counter, setCounter) = useState(CounterStore.counter.value)

useEffectWithCleanup(listOf()) {
val job = CounterStore.counter.onEach { setCounter(it) }.launchIn(GlobalScope)
return@useEffectWithCleanup { job.cancel() }
}

div {
+"Counter: $counter"
}
button {
attrs.onClickFunction = { CounterStore.inc() }
+"Increment"
}
}

我们可以将此 StateFlow 逻辑提取到自定义 React Hook 中:

fun <T> useStateFlow(flow: StateFlow<T>): T {
val (state, setState) = useState(flow.value)

useEffectWithCleanup(listOf()) {
val job = flow.onEach { setState(it) }.launchIn(GlobalScope)
return@useEffectWithCleanup { job.cancel() }
}

return state
}

然后在我们的组件中像这样使用它:

val counter = useStateFlow(CounterStore.counter)

完整工程可见here .Flow-Api 是非常实验性的,所以这可能不是最终的解决方案:)

关于kotlin - kotlin-react useEffect中如何订阅StateFlow,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62690722/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com