
Wrapper for React, React Router, and react-helmet-async, offering a consistent API with improved type safety and reduced performance overhead. Supports coroutines and Concurrent Mode.
Kotlin/JS wrapper for React, React Router and react-helmet-async.
class instead of just external interface.by useState(…) are reflected immediately.CoroutineScope(…) { … }, useCoroutineScope() and useFlow(…).@DslMarker colors.react.component() are memoized by default unless they have children (react.componentWithChildren()).react.component() or added by RComponent.memo() use equals() to compare Props. You must ensure that your props
implement equals() in order to benefit from memoization.equals() instead of ===. They don't need to be an Array nor is the same amount of dependencies needed for each render.exact, strict and sensitive by default.build.gradle.kts:
dependencies {
implementation("io.fluidsonic.react:fluid-react-dom:0.13.0") // basis module
implementation("io.fluidsonic.react:fluid-react-coroutines:0.13.0") // optional coroutine support
implementation("io.fluidsonic.react:fluid-react-helmet:0.13.0") // optional dynamic metadata (react-helmet-async)
implementation("io.fluidsonic.react:fluid-react-router-dom:0.13.0") // optional routing (react-router)
}import io.fluidsonic.react.*
import kotlinx.browser.*
fun main() {
val body = checkNotNull(document.body)
val container = document.createElement("div").also(body::appendChild)
react.createRoot(container).render {
+"Hello world"
EmojiContainer(EmojiContainerProps("😍")) { strong { +"cool" } }
}
}
val EmojiContainer by react.componentWithChildren { props: EmojiContainerProps, children ->
var count by useState(3)
useEffect(count) {
val timerId = window.setTimeout({ count += 1 }, 2000)
cleanup { window.clearTimeout(timerId) }
}
h1 { +"Your emoji, $count times 🎉" }
button {
attrs.onClick = { count += 1 }
+"Add one"
}
ol {
repeat(count) {
li {
+props.emoji
+" "
children()
}
}
}
}
class EmojiContainerProps(val emoji: String)Also check out the playground and run it from IntelliJ IDEA.
Kotlin/JS wrapper for React, React Router and react-helmet-async.
class instead of just external interface.by useState(…) are reflected immediately.CoroutineScope(…) { … }, useCoroutineScope() and useFlow(…).@DslMarker colors.react.component() are memoized by default unless they have children (react.componentWithChildren()).react.component() or added by RComponent.memo() use equals() to compare Props. You must ensure that your props
implement equals() in order to benefit from memoization.equals() instead of ===. They don't need to be an Array nor is the same amount of dependencies needed for each render.exact, strict and sensitive by default.build.gradle.kts:
dependencies {
implementation("io.fluidsonic.react:fluid-react-dom:0.13.0") // basis module
implementation("io.fluidsonic.react:fluid-react-coroutines:0.13.0") // optional coroutine support
implementation("io.fluidsonic.react:fluid-react-helmet:0.13.0") // optional dynamic metadata (react-helmet-async)
implementation("io.fluidsonic.react:fluid-react-router-dom:0.13.0") // optional routing (react-router)
}import io.fluidsonic.react.*
import kotlinx.browser.*
fun main() {
val body = checkNotNull(document.body)
val container = document.createElement("div").also(body::appendChild)
react.createRoot(container).render {
+"Hello world"
EmojiContainer(EmojiContainerProps("😍")) { strong { +"cool" } }
}
}
val EmojiContainer by react.componentWithChildren { props: EmojiContainerProps, children ->
var count by useState(3)
useEffect(count) {
val timerId = window.setTimeout({ count += 1 }, 2000)
cleanup { window.clearTimeout(timerId) }
}
h1 { +"Your emoji, $count times 🎉" }
button {
attrs.onClick = { count += 1 }
+"Add one"
}
ol {
repeat(count) {
li {
+props.emoji
+" "
children()
}
}
}
}
class EmojiContainerProps(val emoji: String)Also check out the playground and run it from IntelliJ IDEA.