React bindings for MoonBit
🚧 This is an early project
This is an experimental hobby project exploring MoonBit bindings for React. The API is unstable and may change frequently. Not recommended for production use. This project is intended for technical exploration and learning purposes only.
render(vdom: VirtualNode, parent: @dom.Element) -> Unit- Render virtual DOM to specified parent elementcomponent[T: JsValueTrait](f: (T) -> VirtualNode, props: T, children: Array[VirtualNode]) -> VirtualNode- Create component
use_state[T](initial: T) -> (T, (T) -> Unit)- State management hookuse_reducer[S: Default, A](initial?: S, reducer: (S, A) -> S) -> (S, (A) -> Unit)- Reducer hookuse_effect_once(effect: () -> Unit) -> Unit- Effect hook that runs only onceuse_effect_deps(effect: () -> Unit, deps: Array[JsObscure]) -> Unit- Effect hook with dependenciesuse_layout_effect_deps(effect: () -> Unit, deps: Array[JsObscure]) -> Unit- Layout effect hookuse_memo_deps[A](factory: () -> A, deps: Array[JsObscure]) -> A- Memoization hookuse_callback_deps[F](callback: F, deps: Array[JsObscure]) -> F- Callback memoization hookuse_callback0_deps(f: () -> Unit, deps: Array[JsObscure]) -> () -> Unit- Zero-argument callback hookuse_ref[T: JsValueTrait](initial: T) -> ReactRef[T]- Reference hookobscure[T](v: T) -> JsObscure- Dependency conversion helper function
div,span,p,h1,h2,h3- Basic text elementsbutton,input,textarea,select,option- Form elementsa,img,video,audio- Media and link elementsul,ol,li- List elementssection,article,header,footer,nav,aside- Semantic elementslabel- Label element
DOMEventtype and its methods:target_value() -> String- Get form element valuekey() -> String,key_code() -> Int- Keyboard eventsclient_x() -> Int,client_y() -> Int- Mouse coordinatesprevent_default(),stop_propagation()- Event controlctrl_key(),shift_key(),alt_key(),meta_key() -> Bool- Modifier key detection
ElementAttrs- HTML attribute managementElementEvents- Event handler managementRespoStyle- CSS styles (from@cssmodule)InputTypeenum - Support for all HTML input types
VirtualNode- Base virtual node typeVirtualElement- Virtual element typeText(String)- Text node
Before writing any MoonBit code, make sure to include the React bindings in your project.
import * as React from "react";
import * as ReactDOMClient from "react-dom/client";
window.React = React;
window.ReactDOMClient = ReactDOMClient;Here's a simple example of how to use this library:
// Define your component props
struct ContainerProps {} derive(Default)
// Implement JsValueTrait for props
impl @react.JsValueTrait for ContainerProps with to_value(_self) -> @dom.JsObscure {
@react.JsObject::new().to_value()
}
impl @react.JsValueTrait for ContainerProps with from_value(
_value : @dom.JsObscure,
) -> ContainerProps {
ContainerProps::default()
}
// Create a functional component
fn comp_container(_v : ContainerProps) -> @react.VirtualNode {
let (counter, set_counter) = @react.use_state(0.0.to_float())
@react.div(
id="container",
style=@css.respo_style(
color=Blue,
font_family="Arial",
padding=10.0 |> Px
),
on_click=fn(_) {
println("clicked \{counter}")
set_counter(counter + 1.0)
},
[
@react.Fragment([@react.Text("Demo: ")]),
@react.Text("Counter \{counter}")
],
)
}
// Render to DOM
fn main {
let window = @dom.window()
let doc = window.document()
let body = doc.body()
let props = ContainerProps::default()
@react.render(
@react.component(comp_container, props, []),
body,
)
println("loaded")
}- Type-safe virtual DOM construction
- React-style hooks (useState)
- CSS-in-JS styling support
- Event handling
- Component composition
This is an early project exploring MoonBit bindings for React. The API is subject to frequent changes and breaking updates. Use at your own risk!
Apache 2.0