8000 State · junerver/ComposeHooks Wiki · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content
Junerver Hou edited this page Nov 29, 2024 · 6 revisions

useState

useState 是对 remember { mutableStateOf() } 的封装,用来方便的在组件中使用状态。

请注意:非空状态使用 useState ,可空状态请使用 _useState,对于非空状态进行了一定的优化,如果是数值类型,将会使用对应的数值状态,而非 MutableState

var byState by useState("by delegate")
TButton(text = "change") {
    byState += "." // 使用方法一致
}

useState 还可以用来创建计算状态/派生状态,来代替使用 derivedStateOf

val canUndo = useState { state.value.past.isNotEmpty() }

如果你希望使用类似 React 的写法,你应该优先使用 useGetState

useAutoReset

一个用来定时恢复默认值的 Hook。

var state by useAutoReset(default = "default value", interval = 2.seconds)
Column {
    Text(text = state)
    TButton(text = "set value") {
        state = "has set new value"
    }
}

修改状态后开始延时 interval 设定的时间,时间结束后恢复未默认值。

useBoolean

管理 boolean 状态的 Hook。

你可以通过解构语法,轻松的获得多个用于管理 boolean 状态的函数:

val (state, toggle, setValue, setTrue, setFalse) = useBoolean(default = true)
  • 传递给函数的值 default 是初始的默认值
  • 通过 state 直接读取 boolean 的状态(State<Boolean>
  • toggle 函数用来切换状态
  • setValue 函数签名为 (Boolean) -> Unit,可以用来设置状态
  • setTrue 设置状态为 true
  • setFalse 设置状态为 false

useCountdown

用来管理倒计时的 Hook。

var show by useState(default = false)    
val (leftTime, formattedRes) = useCountdown(
    optionsOf = {
        leftTime = 10.seconds
        // targetDate = Clock.System.now() + 10.seconds
        // interval = 3.seconds
        onEnd = {
            show = true
        }
    }
)
Text(text = "LeftTime: ${leftTime.value.inWholeSeconds}")
Text(text = formattedRes.value.toString())
if (show) {
    Text(text = "countdown on end!!", color = Color.Green)
}

通过设置 leftTimetargetDate 来配置倒计时的结束时间,使用 interval 配置倒计时间隔

返回值 leftTime 是剩余时间的状态,formattedRes 是格式化的时间,你可以自行使用该值来用于UI显示

data class FormattedRes(
    val days: Int,
    val hours: Int,
    val minutes: Int,
    val seconds: Int,
    val milliseconds: Int,
)

useToggle

用于在两个状态值间切换的 Hook。

val (state, toggle) = useToggle("hello", "world")
val (either, toggleEither) = useToggleEither("example", Random.nextDouble())

Text(text = "current: $state")
TButton(text = "toggle") { toggle() }

Text(
    text = "either: ${
        either.fold(
            { "string: $it" },
            { "double: $it" }
        )
    }"
)
TButton(text = "toggle") { toggleEither() }

默认使用左值

useGetState

useGetState 的使用非常接近于 React 中的使用,在 Compose 中,如果你需要使用解构声明来获得接近 React 的开发体验,请务必使用 useGetState 而非 useState

使用示例:

import xyz.junerver.compose.hooks.invoke

val (state, setState) = useGetState(default)
fun set(num:Int) {
    setState(num)
}
fun add(){
	setState{ it +1 }
}

注意请务必手动导入 import xyz.junerver.compose.hooks.invoke

现在 set 函数的签名从 SetValueFn<T> 变更为 SetValueFn<SetterEither<T>>,如果你需要将 set 函数传递给受控组件,请使用 left 函数进行转换

import xyz.junerver.compose.hooks.left

@Composable
private fun Copy() {
    val (state, setState) = useGetState("")
    val (copy, _) = useClipboard()
    Column {
        TextField(
            value = state.value,
            onValueChange = setState.left(),
            label = { Text("Text to copy") }
        )
        Button(onClick = { copy(state.value) }) {
            Text("Copy to clipboard")
        }
    }
}
Clone this wiki locally
0