Skip to content

junerver/ComposeHooks

Repository files navigation

ComposeHooks

English | 简体中文

License Version maven-central latest releast stars Average time to resolve an issue Percentage of issues still open

Star History

Star History Chart

KMP Support

NOTE: The artifact id is hooks2

implementation("xyz.junerver.compose:hooks2:<latest_release>")

Currently only limited targets are supported:

  • android
  • desktop (jvm)
  • iosarm64
  • iosimulatorarm64
  • iosx64

About

The idea for the project comes from alibaba/hooks, which is a very easy-to-use collection of React Hooks.

It encapsulates most common operations as custom hooks, and useRequest is the top priority. It is designed to be very lightweight, highly configurable, and easy to use.

Therefore, based on this design idea, Hooks that can be used in the Compose project were created using similar API names.

The hooks that have been implemented so far are as follows:

Note: All use functions also have the signature of remember. If you prefer Compose’s naming method, just use rememberXxx!

hook name effect
useRequest Manage network requests and implement: manual and automatic triggering; life cycle callbacks; refresh; mutate changes; cancel requests; polling; Ready; dependency refresh; debounce, throttle; error retry;
useAsync A hook that encapsulates rememberCoroutineScope to make it easier to use coroutines
useBoolean Hook to manage boolean state.
useBackToFrontEffect & useFrontToBackEffect Execute effect when app goes to the background or come back to the foreground
useBatteryInfo* A hook that can get the battery level and if is charging.
useBuildInfo* A hook that can get the brand, model, and version of android.
useClipboard Easy to use Clipboard
useContext just like react
useCountdown A hook for manage countdown.
useCounter A hook that manage counter.
useCreation useCreation is the replacement for useRef.
useDebounce A hook that deal with the debounced value.
useDebounceFn A hook that deal with the debounced function.
useDebounceEffect Debounce your useEffect.
useDisableScreenshot* A hook used to handle the prohibition of screenshots on privacy pages.
useEffect just like react
useEvent Implement lightweight cross-component communication using the subscribe-publish pattern
useFlashlight* A Hook for convenient use of flashlight.
useForm A Hook that can easier control headless component Form
useGetState A Hooks that handle state using destructuring declaration syntax.
useInterval A hook that handles the setInterval timer function.
useKeyboard A Hook that controls the display and hiding of the soft keyboard.
useLatest A Hook that returns the latest value, effectively avoiding the closure problem.
useMount A hook that executes a function after the component is mounted.
useNow A hook that return now date, default format:yyyy-MM-dd HH:mm:ss
useNetwork* A hook for obtaining network connection status and type.
usePersistent A lightweight persistence hook, you need to implement the persistence method yourself (memory persistence is used by default)
usePrevious A Hook to return the previous state.
useReducer just like react
useRef just like react
useScreenInfo* A hook that obtains information about the screen width, height, horizontal and vertical orientation.
useSelector/useDispatch easier to management global state,just like use redux-react
useState just like react
useThrottle A hook that deal with the throttled value.
useThrottleFn A hook that deal with the throttled function.
useThrottleEffect Throttle your useEffect.
useToggle A hook that toggle states.
useTimeout A hook that handles the setTimeout timer function.
useTimestamp A hook that return now timestamp as a reactive state.
useUndo A Hook for handling undo and redo.
useUnmount A hook that executes the function right before the component is unmounted.
useUpdate A hook that returns a function which can be used to force the component to re-render.
useUpdateEffect A hook alike useEffect but skips running the effect for the first time.
useVibrate* A hook that make using vibration feedback easy

Functions marked with * can only be used on Android

Add to dependencies

KMP project

// groovy
implementation 'xyz.junerver.compose:hooks2:<latest_release>'
// kotlin
implementation("xyz.junerver.compose:hooks2:<latest_release>")

Use hooks2 In Android

For pure Android projects, please use the following dependencies(Artifact id:hooks2-android):

implementation("xyz.junerver.compose:hooks2-android:<latest_release>")

If used in ComposeMultiplatform, use artifact id: hooks2

Old version hooks continue to support

If your project does not have performance issues due to recompose , you can continue to use the old version in the Android project, and the bugfix will be synchronized to the old version in subsequent development.

implementation("xyz.junerver.compose:hooks:2.0.3")

Quick Setup

  1. Use useGetState to quickly create controlled components

    val (name, setName, getName) = useGetState("")
    OutlinedTextField(
        value = getName(), // or `name.value`
        onValueChange = setName,
        label = { Text("Input Name") }
    )
  2. Use useEffect to perform component LaunchedEffects

  3. Use useRef to create object references that are not affected by component recompose

    val countRef = useRef(0) // or `val countRef by useRef(0)`
    Button(onClick = {
        countRef.current += 1 // or `countRef += 1`
        println(countRef)
    }) {
        Text(text = "Ref= ${countRef.current}") // or `countRef`
    }
  4. Use useRequest to easily manage network query state

    val (dataState, loadingState, errorState, run) = useRequest(
        requestFn = WebService::login.asRequestFn(), //Encapsulate the corresponding extension functions yourself,to make retrofit friendly
        optionsOf = {
            manual = true
        }
    )
    val data by dataState // obtained `value` through delegate
    val loading  by loadingState
    val error by errorState
    if (loading) {
        Text(text = "loading ....")
    }
    if (data != null) {
        Text(text = "resp: $data")
    }
    if (error != null) {
        Text(text = "error: $error")
    }
    Button(onClick = { run(arrayOf(requestBody)) }) {
        Text(text = "Login")
    }

    useRequest organizes code through a plug-in pattern, the core code is extremely simple, and can be easily extended for more advanced features. Current features include:

    • Automatic/manual request
    • Polling
    • Debounce
    • Throttle
    • Error retry
    • Loading delay
    • SWR(stale-while-revalidate)
    • Caching

For more usage, please refer to wiki and examples

Live Templates

Copy hooks in the Live Templates directory File, paste into C:\Users\<user-name>\AppData\Roaming\Google\AndroidStudio2023.2\templates\

You can easily create code snippets of useState and useRequest through us and ur.

Open Inlay Hints for Kotlin Type

For hooks like useRequest, its return value can deconstruct many objects and functions. It is necessary to enable InlayHint:

Editor - Inlay Hints - Types - Kotlin

ProGuard

If you are using ProGuard you might need to add the following option:

-keep class xyz.junerver.composehooks.** { *; }
-keepclassmembers class xyz.junerver.composehooks.** { *; }
-dontwarn xyz.junerver.composehooks.**

Documentation

Todo:

  • KMP friendly
  • Unit Test
  • CI
  • Complete documentation

参考/Thanks

  1. alibaba/hooks
  2. pavi2410/useCompose

License

Apache License 2.0