jsMain.styled.StructEffects.kt Maven / Gradle / Ivy
package styled
import react.*
internal fun useStructMemo(
vararg dependencies: Any?,
callback: () -> T,
): T {
return rawUseMemo(getMemoizedCallback(dependencies, callback), dependencies)
}
@JsModule("react")
@JsNonModule
external object ReactModule
private val supportsInsertionEffect by kotlin.lazy { ReactModule.asDynamic().useInsertionEffect != undefined }
internal fun useCustomInsertionEffect(
vararg dependencies: Any?,
effect: EffectBuilder.() -> Unit,
) {
if (supportsInsertionEffect) {
useInsertionEffect(*dependencies, effect = effect)
} else {
useLayoutEffect(*dependencies, effect = effect)
}
}
private data class MemoizedResult(
val args: Array,
val value: T,
val cleanups: Array,
) {
fun cleanup() {
cleanups.forEach { it() }
}
}
private fun MutableRefObject>.runCallback(
callback: () -> T,
args: Array,
): T {
current?.apply {
if (argsEqual(args)) return value
}
val cleanups = arrayOf()
return callback().also { result ->
current = MemoizedResult(args, result, cleanups)
}
}
private fun getMemoizedCallback(
args: Array,
callback: () -> T,
): () -> T {
val prevResultRef = useRef>(null)
return {
prevResultRef.runCallback(callback, args)
}
}
private fun MemoizedResult?.argsEqual(args: Array): Boolean {
if (this == null) return false
if (this.args.size != args.size) {
if (isDevelopment()) console.warn("Calling useEffect with different number of dependencies: ${this.args.joinToString()} and ${args.joinToString()}")
return false
}
var index = -1
return this.args.all { prevArg: Any ->
index++
val newArg: Any = args[index]
prevArg == newArg
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy