Hi all! Is there any proper way to put in onClick/...
# react
j
Hi all! Is there any proper way to put in onClick/onTextChange things in functionalComponents? I made some extension functions to help out here:
Copy code
fun <T> CommonAttributeGroupFacade.onClick(argument: T, func: (T) -> Unit) {
    onClickFunction = useCallback(
        callback = {
            func(argument)
        },
        dependencies = arrayOf(argument)
    )
}

var CommonAttributeGroupFacade.onClick: () -> Unit
    get() = throw UnsupportedOperationException("You can't read variable onClick")
    set(newValue) {
        onClickFunction = useCallback(
            callback = {
                newValue()
            },
            dependencies = emptyArray()
        )
    }

var CommonAttributeGroupFacade.onTextChange: (String) -> Unit
    get() = throw UnsupportedOperationException("You can't read variable onChange")
    set(newValue) {
        onChangeFunction = useCallback(
            callback = { event: Event ->
                newValue(event.target.asDynamic().value as String)
            },
            dependencies = emptyArray()
        )
    }
The only problem I have is: if I have a list where I can add/remove items, where the list items use one of these (for example onclick), I will get (logically) errors about not having the same amount of hooks when I add/remove list items. To solve that problem, I created a useList method that wraps the list in a functional component and gets recreated on data changes:
Copy code
fun <T : BaseListItem> RBuilder.useList(
    list: List<T>,
    vararg classMap: Pair<ListStyle, String>,
    block: ListElementBuilder<UL, ListProps>.(List<T>) -> Unit
) {
    useCallback(
        functionalComponent<RProps> { list(classMap = *classMap, block = { block(list) }) },
        arrayOf(list)
    ).also { child(it) }
}
Which gives the issue of having a sluggish list during a lot of interactions (for example typing into a list element).
a
Usually I’d have each item in the list be a separate component, and that component can then easily call useCallback just once. (Although I use React much more from just JS than Kotlin)