Skip to content

Utilities

Junerver Hou edited this page Jul 22, 2025 · 2 revisions

useAsync

useAsync 是一个用于处理异步操作的 Hook,提供了多种方式来执行异步任务。

基本用法

// 方式一:接收一个 suspend 函数,返回一个执行函数
val fetchData = useAsync { 
    // 异步操作,例如网络请求
    delay(1000)
    "Fetched data"
}

TButton(text = "Fetch Data") {
    fetchData() // 调用执行异步操作
}

简化协程作用域用法

// 方式二:类似于 scope.launch 的简化用法
val asyncRun = useAsync()

TButton(text = "Run Async") {
    asyncRun {
        // 异步操作
        delay(1000)
        // 处理结果
    }
}

可取消的异步操作

// 方式三:可取消的异步操作
val (run, cancel, active) = useCancelableAsync()

Column {
    Text("Active: ${active.value}")
    
    TButton(text = "Start", enabled = !active.value) {
        run {
            // 长时间运行的异步操作
            delay(5000)
            "Operation completed"
        }
    }
    
    TButton(text = "Cancel", enabled = active.value) {
        cancel() // 取消正在进行的操作
    }
}

useClipboard

useClipboard 提供了与系统剪贴板交互的功能,允许复制和粘贴文本内容。

val (copy, paste) = useClipboard()

Column {
    var inputText by useState("")
    var outputText by useState("")
    
    OutlinedTextField(
        value = inputText,
        onValueChange = { inputText = it },
        label = { Text("输入文本") }
    )
    
    Row {
        TButton(text = "复制到剪贴板") {
            copy(inputText) // 复制文本到剪贴板
        }
        
        TButton(text = "从剪贴板粘贴") {
            outputText = paste() // 从剪贴板获取文本
        }
    }
    
    Text("剪贴板内容: $outputText")
}

useCycleList

useCycleList 用于在列表项之间循环,提供了移动到下一项、上一项或特定项的功能。

val colors = listOf("Red", "Green", "Blue", "Yellow", "Purple")
val (current, next, prev, setCurrent, index) = useCycleList(
    items = colors,
    initialValue = "Red" // 可选,默认为列表第一项
)

Column {
    Text("当前颜色: ${current.value}")
    Text("索引: ${index.value}")
    
    Row {
        TButton(text = "上一个") {
            prev() // 移动到上一项
        }
        
        TButton(text = "下一个") {
            next() // 移动到下一项
        }
    }
    
    // 直接设置为特定项
    TButton(text = "设置为蓝色") {
        setCurrent("Blue")
    }
}

useCounter

useCounter 提供了计数器功能,支持递增、递减、设置和重置操作,并可配置最小值和最大值。

// 基本用法
val (count, inc, dec, set, reset) = useCounter()

Column {
    Text("计数: ${count.value}")
    
    Row {
        TButton(text = "+") { inc() } // 递增
        TButton(text = "-") { dec() } // 递减
    }
    
    TButton(text = "设置为 10") { set(10) } // 设置为特定值
    TButton(text = "重置") { reset() } // 重置为初始值
}

// 带边界的计数器
val (boundedCount, boundedInc, boundedDec) = useCounter(
    min = 0,
    max = 10,
    initial = 5
)

Column {
    Text("带边界的计数: ${boundedCount.value}")
    
    Row {
        TButton(text = "+", enabled = boundedCount.value < 10) { boundedInc() }
        TButton(text = "-", enabled = boundedCount.value > 0) { boundedDec() }
    }
}

useEvent

useEvent 提供了组件间通信的能力,类似于事件总线,父组件可以通过发布事件从而调用子组件的函数。包含 useEventSubscribeuseEventPublish 两个函数。

// 在父组件中发布事件
val post = useEventPublish<String>()
// 触发事件
TButton(text = "发送事件") {
    post("Hello from parent") // 发布事件,所有订阅者都会收到
}

// 在子组件中订阅事件
@Composable
fun ChildComponent() {
    useEventSubscribe<String> { message ->
        // 处理接收到的事件
        println("Received: $message")
    }
    
    // 组件内容
}

useThrottleuseThrottleFn

useThrottle 用于限制状态更新的频率,而 useThrottleFn 用于限制函数调用的频率。

// 节流状态
var inputValue by useState("")
val throttledValue by useThrottle(inputValue) {
    wait = 500.milliseconds
    leading = true
    trailing = true
}

// 节流函数
val throttledFn = useThrottleFn<Unit>(
    fn = {
        // 执行频率受限的操作,如API调用
    },
    optionsOf = {
        wait = 1.seconds
        leading = true
        trailing = true
    }
)

TButton(text = "执行操作") {
    throttledFn() // 无论点击多快,函数最多每秒执行一次
}

useDebounceuseDebounceFn

useDebounce 用于延迟状态更新,而 useDebounceFn 用于延迟函数调用,直到经过指定的等待时间。

// 防抖状态
var searchQuery by useState("")
val debouncedQuery by useDebounce(searchQuery) {
    wait = 500.milliseconds
    leading = false
    trailing = true
}

// 防抖函数
val debouncedSearch = useDebounceFn<String>(
    fn = { query ->
        // 执行搜索操作,只有在用户停止输入500ms后才会执行
    },
    optionsOf = {
        wait = 500.milliseconds
    }
)

OutlinedTextField(
    value = searchQuery,
    onValueChange = {
        searchQuery = it
        debouncedSearch(it)
    }
)

useUndo

useUndo 提供了撤销/重做功能,通过管理值的历史记录。

val (state, set, reset, undo, redo, canUndo, canRedo) = useUndo(initialPresent = "")
val (input, setInput) = useControllable("")

Column {
    OutlinedTextField(value = input.value, onValueChange = setInput)
    
    TButton(text = "提交") {
        set(input.value) // 设置新值并记录历史
        setInput("") // 清空输入
    }
    
    Row {
        TButton(text = "重置") { reset("") } // 重置所有历史
        TButton(text = "撤销", enabled = canUndo.value) { undo() } // 撤销到上一个值
        TButton(text = "重做", enabled = canRedo.value) { redo() } // 重做到下一个值
    }
    
    Text("结果:\n${state.value}")
}

useUpdate

useUpdate 提供了一种强制组件重新渲染的方法,适用于不直接与状态变化相关的UI更新。

val update = useUpdate()

Column {
    Text("当前时间戳: ${Timestamp.now()}")
    
    TButton(text = "更新") {
        update() // 强制组件重新渲染
    }
}

Clone this wiki locally