frender

Crates.io docs.rs GitHub license GitHub stars

![frender logo](./logo.svg) Functional Rendering: `React` in `Rust`

frender is still in alpha and it's api might change. For now it is recommended to specify the exact version in Cargo.toml. Before updating, please see the full changelog in case there are breaking changes.

There are some example apps in examples folder. You can preview them at this site.

Quick Start

  1. Create a new cargo project

    sh cargo new my-frender-app cd my-frender-app

  2. Add frender to dependencies in Cargo.toml.

    toml [dependencies] frender = "= 1.0.0-alpha.6"

  3. Create index.html in the project root directory.

    html <!DOCTYPE html> <html> <head> <meta charset="UTF-8" /> <title>My frender App</title> <script src="https://unpkg.com/react@17/umd/react.development.js"></script> <script src="https://unpkg.com/react-dom@17/umd/react-dom.development.js"></script> <link data-trunk rel="rust" href="Cargo.toml" /> </head> <body> <div id="frender-root"></div> </body> </html>

  4. Modify src/main.rs

    ```rust use frender::prelude::*;

    [component(main(mountelementid = "frender-root"))]

    fn Main() { rsx!(

    "Hello, frender!"
    ) } ```

  5. Run with trunk

    Install trunk and then execute:

    sh trunk serve

    Then you can navigate to http://localhost:8080 to see your frender app.

rsx syntax

rsx element

```rust use frender::prelude::*;

rsx! ( // Child node can be any literal strings or numbers "some string" 1 // Child node can be any rust expressions wrapped in braces { 1 + 6 } { value } // Child node can be an element

// Prop without value means `true`, just like React
<MyDialog show />

// Fragment
<>1 2 3</>
// Fragment with key
<# key="key">1 2 3</#>

// you can also use `</_>` to enclose any element
<path::to::Component></_>
// the above is equivalent to:
<path::to::Component></path::to::Component>

) ```

Any component name starting with lower case letter [a-z] will be interpreted as an intrinsic component. For example, rsx!( <div id="my-div" /> ) will be resolved to:

```rust use frender::prelude::; use self::intrinsic_components::div::prelude::;

rsx! ( ) ```

rsx prop

In order to make rsx less verbose, frender provides IntoPropValue trait. The value in <MyComponent prop={value} /> will be mapped to IntoPropValue::into_prop_value(value).

With this, assuming the prop accepts Option<i32>, you can simplify prop={Some(1)} to prop={1}, because T implements IntoPropValue<Option<T>>.

If you want to pass the value as is, you can use := to set prop. prop:={value}

Write a component

Component with no props

```rust use frender::prelude::*;

[component]

fn MyComponent() { // ^ // the return type defaults to react::Element rsx!(

) }

// Or you can specify the return type explicitly

[component]

fn MyAnotherComponent() -> Option { if check_something() { Some(rsx!( )) } else { None } } ```

Component with props

First, define MyProps

```rust use frender::prelude::*;

defprops! { pub struct MyProps { // Required prop name: String, // Optional prop which defaults to Default::default() age: Option, // If the prop type is not specified, // then frender will infer the type by prop name. // For example, class_name default has type Option<String> classname?, // Prop can also have type generics. // For example, the following is // the default definition for prop children children(value: Option) -> Option { value.andthen(react::Node::intochildren) }, } } ```

Then write the component with the above props:

```rust use frender::prelude::*;

[component]

pub fn MyComponent(props: &MyProps) { rsx!(

{&props.children}
) } ```

Due to the generics, in some very rare cases, you may meet errors like type annotations needed cannot infer type for type parameter. You can solve it by specifying the type with the turbofish syntax ::<>. For example:

rust rsx! ( // ERROR: type annotations needed <a children={None} /> ) rsx! ( // it works! <a children={None::<()>} /> )

Hooks

React hooks are also available in frender.

You checkout the examples for the usage.

Future Development Plans

Contributing

frender is open sourced at GitHub. Pull requests and issues are welcomed.

You can also sponsor me and I would be very grateful :heart:

Buy Me a Coffee at ko-fi.com