Skip to content

use React style hooks in Compose Multiplatform to easier management state

License

Notifications You must be signed in to change notification settings

junerver/ComposeHooks

Repository files navigation

ComposeHooks

English | 简体中文

LicenseVersion maven-centrallatest releaststarsAverage time to resolve an issuePercentage of issues still openAsk DeepWikiklibs.io

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!

Hooks

State

hook namedescription
useAutoResetA hook which will reset state to the default value after some time.
useBooleanHook to manage boolean state.
useContextjust like react
useCreationuseCreation is the replacement for useRef.
useDebounceA hook that deal with the debounced value.
Form.useFormA Hook that can easier control headless component Form
useGetStateA Hooks that handle state using destructuring declaration syntax.
useImmutableListA hook for managing immutable lists in Compose.
useLastChangedA Hook that records the Instant of the last change
useLatestA Hook that returns the latest value, effectively avoiding the closure problem.
usePersistentA lightweight persistence hook, you need to implement the persistence method yourself (memory persistence is used by default)
usePreviousA Hook to return the previous state.
useReducerjust like react
useRefjust like react
useResetStateA hook for managing state with reset functionality.
useSelectableA utility function to help implement select or multi select feature.
useSelector/useDispatcheasier to management global state,just like use redux-react
useStatejust like react
useStateMachineA Compose Hook for managing state machines
useThrottleA hook that deal with the throttled value.
useToggleA hook that toggle states.

Effect

hook namedescription
useBackToFrontEffect & useFrontToBackEffectExecute effect when app goes to the background or come back to the foreground
useEffectjust like react
useDebounceEffectDebounce your useEffect.
useThrottleEffectThrottle your useEffect.
useUpdateEffectA hook alike useEffect but skips running the effect for the first time.
usePausableEffectA pausable effect hook that provides the ability to pause, resume, and stop effect execution

LifeCycle

hook namedescription
useMountA hook that executes a function after the component is mounted.
useUnmountA hook that executes the function right before the component is unmounted.

Time

hook namedescription
useDateFormatGet the formatted date according to the string of tokens passed in, inspired by dayjs.
useIntervalA hook that handles the setInterval timer function.
useNowA hook that return now date, default format: yyyy-MM-dd HH:mm:ss
useTimeAgoReactive time ago. Automatically update the time ago string when the time changes.
useTimeoutA hook that handles the setTimeout timer function.
useTimeoutFnA hook for executing a function after a specified delay with controls.
useTimeoutPollUse timeout to poll for content. Triggers the callback after the last task is completed.
useTimestampA hook that return now timestamp as a reactive state.

Math

hook namedescription
Reactive kotlin.math.abs.
useCeilReactive kotlin.math.ceil
useRoundReactive kotlin.math.round
useTruncReactive kotlin.math.truncate
useMinReactive kotlin.math.min
useMaxReactive kotlin.math.max
usePowReactive kotlin.math.pow
useSqrtReactive kotlin.math.sqrt

Utilities

hook namedescription
useAsyncA hook that encapsulates rememberCoroutineScope to make it easier to use coroutines
useBiometric*use biometrics conveniently
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.
useClipboardEasy to use Clipboard
useCountdownA hook for manage countdown.
useCounterA hook that manage counter.
useCycleListCycle through a list of items.
useDebounceFnA hook that deal with the debounced function.
useDisableScreenshot*A hook used to handle the prohibition of screenshots on privacy pages.
useEventImplement lightweight cross-component communication using the subscribe-publish pattern
useFlashlight*A Hook for convenient use of flashlight.
useIdelTracks whether the user is being inactive.
useKeyboardA Hook that controls the display and hiding of the soft keyboard.
useNetwork*A hook for obtaining network connection status and type.
useRequestManage network requests and implement: manual and automatic triggering; life cycle callbacks; refresh; mutate changes; cancel requests; polling; Ready; dependency refresh; debounce, throttle; error retry;
useScreenInfo*A hook that obtains information about the screen width, height, horizontal and vertical orientation.
useSortedA hook that helps you reactive sort array
useThrottleFnA hook that deal with the throttled function.
useUndoA Hook for handling undo and redo.
useUpdateA hook that returns a function which can be used to force the component to re-render.
useVibrate*A hook that make using vibration feedback easy

Functions marked with * can only be used on Android

AI Module

A separate AI module providing hooks for AI chat completions and structured data generation with OpenAI-compatible APIs and Anthropic Messages API.

Add AI module dependency:

implementation("xyz.junerver.compose:ai:<latest_release>")
hook namedescription
useChatA hook for managing chat conversations with OpenAI-compatible APIs and Anthropic Messages API, supporting streaming responses with typewriter effect.
useAgentA hook for multi-step tool calling (agent loop) built on top of useChat.
useGenerateObjectA hook for generating structured data objects from AI responses, supports streaming and incremental object updates.

Features:

  • Streaming responses (SSE) with real-time typewriter effect
  • Non-streaming mode support (stream = false)
  • Multimodal input support (text, images, files)
  • Structured data generation with type safety
  • Message state management
  • Loading and error states
  • Control functions (send, stop, reload)
  • Configurable options (temperature, maxTokens, timeout, etc.)
  • Lifecycle callbacks (onFinish, onError, onStream)

Example - Chat:

val (messages, isLoading, error, sendMessage, _, _, reload, stop) = useChat{provider =Providers.OpenAI(apiKey ="your-api-key") model ="gpt-3.5-turbo" systemPrompt ="You are a helpful assistant." onFinish ={message, usage, reason ->println("Completed: ${message.content}") } } // Send a message sendMessage("Hello!") // Display messages with streaming effect messages.value.forEach{message ->Text("${message.role}: ${message.content}") }

Example - Generate Object:

@Serializable data classRecipe(valname:String, valingredients:List<String>) val (recipe, rawJson, isLoading, error, submit, stop) = useGenerateObject<Recipe>( schema =Recipe::class.jsonSchemaString, ){provider =Providers.OpenAI(apiKey ="your-api-key") systemPrompt ="You are a professional chef." } // Generate structured data submit("Generate a pasta recipe") // Use the result recipe.value?.let{r ->Text("Recipe: ${r.name}") r.ingredients.forEach{Text("- $it") } }

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 delegateval 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
  • CI
  • Unit Test
  • Complete documentation

参考/Thanks

  1. alibaba/hooks
  2. pavi2410/useCompose
  3. vueuse/vueuse

Contributing Guidelines

Contributing guidelines

License

Apache License 2.0

Contributors 3

  •  
  •  
  •  

Languages