Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

fluidsonic/fluid-react

Open more actions menu

Repository files navigation

fluid-react

Maven Central Kotlin React #fluid-libraries Slack Channel

Kotlin/JS wrapper for React, React Router and react-helmet-async.

  • Similar to kotlin-react.
  • Nicer and consistent API. Easier to use.
  • Not multiplatform. Optimized for Kotlin/JS instead.
  • Lower size and performance overhead.
  • More type safety, esp. around hooks.
  • With new Concurrent Mode in mind, thus depending on experimental React releases.
  • Props allow class instead of just external interface.
  • Updates of local properties delegated with by useState(…) are reflected immediately.
  • Support for coroutines with CoroutineScope(…) { … }, useCoroutineScope() and useFlow(…).
  • @DslMarker colors.
  • Experimental and IR compiler only. Relies on compiler-internal behavior until KT-10468 is solved.
  • Contributions welcome 😃
  • Kotlin/JS-optimized CSS library with nice API in the works.

Notable differences in behavior

  • Components created with react.component() are memoized by default unless they have children (react.componentWithChildren()).
  • Memoization of components created with 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.
  • Hook dependencies use equals() instead of ===. They don't need to be an Array nor is the same amount of dependencies needed for each render.
  • Router routes are exact, strict and sensitive by default.

Installation

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)
}

Example

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.

About

Highly experimental Kotlin wrapper for React

Topics

Resources

License

Stars

Watchers

Forks

Languages

Morty Proxy This is a proxified and sanitized view of the page, visit original site.