-
Notifications
You must be signed in to change notification settings - Fork 7
迁移到hooks2 的说明
从 hooks 迁移到 kmp 版本的 hooks2 有以下注意事项:
如果你在需要使用配置的hooks中直接使用使用了optionsOf,并且没有使用命名参数 :
val (resume, pause, isActive) = useInterval(
optionsOf {
initialDelay = 2.seconds
period = 1.seconds
}
) 需要修改为:
val (resume, pause, isActive) = useInterval(
optionsOf = {
initialDelay = 2.seconds
period = 1.seconds
}
)RequestOptions的参数 debounceOptions、throttleOptions,需要替换为各自的 optionOf 函数:
DebounceOptions.optionOf { }ThrottleOptions.optionOf { }
替换:
第一步替换 debounceOptions、throttleOptions
-
debounceOptions = optionsOf {替换为debounceOptions = DebounceOptions.optionOf { -
throttleOptions = optionsOf {替换为throttleOptions = ThrottleOptions.optionOf {
第二步:全局替换 options = optionsOf { 为 optionsOf = {
第三步:替换 optionsOf { 为 optionsOf = {
这个函数几乎不应该在用户侧调用,因为所有需要默认参数的函数都已经赋值,如果你现在确实需要一个默认的选项对象
使用Options.optionOf{}
纯Android项目请使用如下依赖:
implementation("xyz.junerver.compose:hooks2-android:<latest_release>")在过去的版本为了使用方便,大多数的api都是直接返回了状态的值,这很方便,但是也带来了一些潜在的性能问题,例如下面的代码:
@Composable
private fun TestDeferReads() {
var byState by useState("default1")
val (state,setState,getState) = useGetState("getState")
Column(modifier = Modifier.randomBackground().size(200.dp, 300.dp)) {
//by委托
Button(onClick = {
byState+="1"
}) { Text(byState) }
//triple 解构
Button(onClick = {
setState(getState()+"2")
}) { Text(state) }
}
}我们点击第一个按钮,Column的背景色不会发生改变,说明该组件没有发生重组。当我们点击第二个按钮时,Column 组件背景色发生变化,证明其发生了重组。
原因很简单,在 Compose 中读取状态的操作才是真正触发重组的关键,只有读取了State,组件才会因为State变化而进入了重组,如果只是声明了State而没有直接读取State的值,State变化后是不会导致当前组件重组的。
在一些复杂的页面中必然存在大量的类似 Column 这样的内联组件,在一个复杂的组件树中,这样的重组可能会带来性能问题。
所以在 hooks2 中将不再直接返回 状态的值(不在hook调用处触发读取),而是返回只读状态本身,在组件中需要值时,通过 state.value 获取(延迟读取)
简而言之,hook将从返回状态值
T,修改成返回状态State<T>
涉及的 hooks :
useGetStateuseBooleanuseCounteruseCountdownuseDebounceuseResetStateuseReduceruseSelectoruseTimestampuseIntervaluesThrottleusePrevioususeUndouseNow
对于返回元组的,你需要修改代码为 state.value,来使用状态的值。对于 useDebounce、uesThrottle、useSelector 等只返回状态的,可以简单的通过修改 = 为 by
例如:
// 修改前
val (state, setState, getState) = useGetState("getState")
Column(modifier = Modifier.randomBackground().size(200.dp, 300.dp)) {
Button(onClick = {
setState(getState() + "1")
}) { Text(state) } //此处可以直接使用state的值
}
// 修改后
val (state, setState, getState) = useGetState("getState")
Column(modifier = Modifier.randomBackground().size(200.dp, 300.dp)) {
Button(onClick = {
setState(getState() + "2")
}) { Text(state.value) } //改为 state.value
}useRequest 未进行 State 包裹,考虑到网络请求一般都是在当前组件内消费状态,所以即使读取状态值触发组件刷新也不会引起大范围的重组,二来考虑到网络请求状态众多,如果进行状态包裹,易用性会打折扣。