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.
Create a new cargo project
sh
cargo new my-frender-app
cd my-frender-app
Add frender
to dependencies in Cargo.toml
.
toml
[dependencies]
frender = "= 1.0.0-alpha.7"
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>
Modify src/main.rs
```rust use frender::prelude::*;
fn Main() { rsx!(
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
syntaxrsx
element```rust use frender::prelude::*;
rsx! (
// 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
propIn 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}
```rust use frender::prelude::*;
fn MyComponent() { // ^ // the return type defaults to react::Element rsx!(
) }// Or you can specify the return type explicitly
fn MyAnotherComponent() -> Option
First, define MyProps
```rust use frender::prelude::*;
defprops! {
pub struct MyProps {
// Required prop
name: String,
// Optional prop which defaults to Default::default()
age: Optionclass_name
default has type Option<String>
classchildren
children
Then write the component with the above props:
```rust use frender::prelude::*;
pub fn MyComponent(props: &MyProps) { rsx!(
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::<()>} />
)
React hooks are also available in frender
.
You checkout the examples for the usage.
frender
components to jsCssProperties
emotion/react
)frender
is open sourced at GitHub.
Pull requests and issues are welcomed.
You can also sponsor me and I would be very grateful :heart: