Basic docs cleanups
This commit is contained in:
3 files changed
+39
-97
No files matched your search
@@ -104,7 +104,7 @@ pub fn component(_args: TokenStream, input: TokenStream) -> TokenStream {
|
||||
/// ```rust,ignore
|
||||
/// #[inline_props]
|
||||
/// fn app(bob: String) -> Element {
|
||||
/// rsx!("hello, {bob}"))
|
||||
/// rsx! { "hello, {bob}") }
|
||||
/// }
|
||||
///
|
||||
/// // is equivalent to
|
||||
@@ -114,8 +114,8 @@ pub fn component(_args: TokenStream, input: TokenStream) -> TokenStream {
|
||||
/// bob: String,
|
||||
/// }
|
||||
///
|
||||
/// fn app(cx: Scope<AppProps>) -> Element {
|
||||
/// rsx!("hello, {bob}"))
|
||||
/// fn app(props: AppProps) -> Element {
|
||||
/// rsx! { "hello, {bob}") }
|
||||
/// }
|
||||
/// ```
|
||||
#[proc_macro_attribute]
|
||||
|
||||
@@ -34,11 +34,11 @@ Remember: Dioxus is a library for declaring interactive user interfaces—it is
|
||||
|
||||
## Brief Overview
|
||||
|
||||
All Dioxus apps are built by composing functions that return an `Element`.
|
||||
All Dioxus apps are built by composing functions that return an `Element`.
|
||||
|
||||
To launch an app, we use the `launch` method and use features in ``Cargo.toml`` to specify which renderer we want to use. In the launch function, we pass the app's root `Component`.
|
||||
|
||||
```rust, ignore
|
||||
```rust
|
||||
use dioxus::prelude::*;
|
||||
|
||||
fn main() {
|
||||
@@ -49,7 +49,7 @@ fn main() {
|
||||
// It's not required, but highly recommended. For example, UpperCamelCase components will not generate a warning.
|
||||
#[component]
|
||||
fn App() -> Element {
|
||||
rsx!("hello world!")
|
||||
rsx! { "hello world!" }
|
||||
}
|
||||
```
|
||||
|
||||
@@ -67,25 +67,25 @@ children.
|
||||
```rust, ignore
|
||||
let value = "123";
|
||||
|
||||
rsx!(
|
||||
rsx! {
|
||||
div {
|
||||
class: "my-class {value}", // <--- attribute
|
||||
onclick: move |_| info!("clicked!"), // <--- listener
|
||||
h1 { "hello world" }, // <--- child
|
||||
}
|
||||
)
|
||||
}
|
||||
```
|
||||
|
||||
The `rsx!` macro accepts attributes in "struct form" and will parse the rest
|
||||
of the body as child elements and rust expressions. Any rust expression that
|
||||
implements `IntoIterator<Item = impl IntoVNode>` will be parsed as a child.
|
||||
The `rsx!` macro accepts attributes in "struct form". Any rust expression contained within curly braces that implements `IntoIterator<Item = impl IntoVNode>` will be parsed as a child. We make two exceptions: both `for` loops and `if` statements are parsed where their body is parsed as a child.
|
||||
|
||||
```rust, ignore
|
||||
rsx!(
|
||||
rsx! {
|
||||
div {
|
||||
(0..10).map(|_| rsx!(span { "hello world" }))
|
||||
for _ in 0..10 {
|
||||
span { "hello world" }
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
```
|
||||
|
||||
The `rsx!` macro is what generates the `Element` that our components return.
|
||||
@@ -93,7 +93,7 @@ The `rsx!` macro is what generates the `Element` that our components return.
|
||||
```rust, ignore
|
||||
#[component]
|
||||
fn Example() -> Element {
|
||||
rsx!("hello world")
|
||||
rsx!{ "hello world" }
|
||||
}
|
||||
```
|
||||
|
||||
@@ -104,20 +104,14 @@ elements:
|
||||
#[component]
|
||||
fn App() -> Element {
|
||||
let name = "dave";
|
||||
rsx!(
|
||||
rsx! {
|
||||
h1 { "Hello, {name}!" }
|
||||
div {
|
||||
class: "my-class",
|
||||
id: "my-id",
|
||||
|
||||
(0..5).map(|i| rsx!(
|
||||
div { key: "{i}"
|
||||
"FizzBuzz: {i}"
|
||||
}
|
||||
))
|
||||
|
||||
div { class: "my-class", id: "my-id",
|
||||
for i in 0..5 {
|
||||
div { "FizzBuzz: {i}" }
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
@@ -125,19 +119,19 @@ fn App() -> Element {
|
||||
|
||||
We can compose these function components to build a complex app. Each new
|
||||
component we design must take some Properties. For components with no explicit
|
||||
properties, we can use the `()` type or simply omit the type altogether.
|
||||
properties we can omit the type altogether.
|
||||
|
||||
In Dioxus, all properties are memoized by default!
|
||||
In Dioxus, all properties are memoized by default, and this implement both Clone and PartialEq. For props you can't clone, simply wrap the fields in a ReadOnlySignal and Dioxus will handle the wrapping for you.
|
||||
|
||||
```rust, ignore
|
||||
#[component]
|
||||
fn App() -> Element {
|
||||
rsx!(
|
||||
rsx! {
|
||||
Header {
|
||||
title: "My App",
|
||||
color: "red",
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
@@ -154,12 +148,12 @@ struct HeaderProps {
|
||||
|
||||
#[component]
|
||||
fn Header(props: HeaderProps) -> Element {
|
||||
rsx!(
|
||||
rsx! {
|
||||
div {
|
||||
background_color: "{props.color}"
|
||||
h1 { "{props.title}" }
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
@@ -169,35 +163,12 @@ struct from function arguments:
|
||||
```rust, ignore
|
||||
#[component]
|
||||
fn Header(title: String, color: String) -> Element {
|
||||
rsx!(
|
||||
rsx! {
|
||||
div {
|
||||
background_color: "{color}"
|
||||
h1 { "{title}" }
|
||||
}
|
||||
)
|
||||
}
|
||||
```
|
||||
|
||||
Components may also borrow data from their parent component. We just need to
|
||||
attach some lifetimes to the props struct.
|
||||
|
||||
> Note: we don't need to derive `PartialEq` for borrowed props since they cannot be memoized.
|
||||
|
||||
```rust, ignore
|
||||
#[derive(Props)]
|
||||
struct HeaderProps<'a> {
|
||||
title: &'a str,
|
||||
color: &'a str,
|
||||
}
|
||||
|
||||
#[component]
|
||||
fn Header<'a>(props: HeaderProps<'a>) -> Element {
|
||||
rsx!(
|
||||
div {
|
||||
background_color: "{props.color}"
|
||||
h1 { "{props.title}" }
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
@@ -205,23 +176,11 @@ Components that begin with an uppercase letter may be called with
|
||||
the traditional (for React) curly-brace syntax like so:
|
||||
|
||||
```rust, ignore
|
||||
rsx!(
|
||||
rsx! {
|
||||
Header { title: "My App" }
|
||||
)
|
||||
}
|
||||
```
|
||||
|
||||
Alternatively, if your components begin with a lowercase letter, you can use
|
||||
the function call syntax:
|
||||
|
||||
```rust, ignore
|
||||
rsx!(
|
||||
header( title: "My App" )
|
||||
)
|
||||
```
|
||||
|
||||
However, the convention is to use UpperCamelCase. The `#[component]` attribute will enforce this,
|
||||
but you can turn it off if you wish.
|
||||
|
||||
## Hooks
|
||||
|
||||
While components are reusable forms of UI elements, hooks are reusable forms
|
||||
@@ -236,7 +195,7 @@ use hooks to define the state and modify it from within listeners.
|
||||
fn App() -> Element {
|
||||
let name = use_signal(|| "world");
|
||||
|
||||
rsx!("hello {name}!")
|
||||
rsx! { "hello {name}!" }
|
||||
}
|
||||
```
|
||||
|
||||
@@ -263,7 +222,7 @@ fn use_username(d: Uuid) -> bool {
|
||||
To create entirely new foundational hooks, we can use the `use_hook` method.
|
||||
|
||||
```rust, ignore
|
||||
fn use_mut_string() -> &mut String {
|
||||
fn use_mut_string() -> String {
|
||||
use_hook(|_| "Hello".to_string())
|
||||
}
|
||||
```
|
||||
@@ -283,12 +242,12 @@ fn main() {
|
||||
|
||||
#[component]
|
||||
fn App() -> Element {
|
||||
let count = use_signal(|| 0);
|
||||
let mut count = use_signal(|| 0);
|
||||
|
||||
rsx!(
|
||||
div { "Count: {count}" }
|
||||
button { onclick: move |_| count.set(count + 1), "Increment" }
|
||||
button { onclick: move |_| count.set(count - 1), "Decrement" }
|
||||
button { onclick: move |_| count += 1, "Increment" }
|
||||
button { onclick: move |_| count -= 1, "Decrement" }
|
||||
)
|
||||
}
|
||||
```
|
||||
@@ -311,21 +270,4 @@ Beyond this overview, Dioxus supports:
|
||||
- Basic fine-grained reactivity (IE SolidJS/Svelte)
|
||||
- and more!
|
||||
|
||||
Good luck!
|
||||
|
||||
## Inspiration, Resources, Alternatives, and Credits
|
||||
|
||||
Dioxus is inspired by:
|
||||
|
||||
- React: for its hooks, concurrency, suspense
|
||||
- Dodrio: for its research in bump allocation, double buffering, and diffing architecture
|
||||
|
||||
Alternatives to Dioxus include:
|
||||
|
||||
- Yew: supports function components and web, but no SSR, borrowed data, or bump allocation. Rather slow at times.
|
||||
- Percy: supports function components, web, ssr, but lacks state management
|
||||
- Sycamore: supports function components, web, ssr, but is closer to SolidJS than React
|
||||
- MoonZoom/Seed: opinionated frameworks based on the Elm model (message, update)—no hooks
|
||||
|
||||
We've put a lot of work into making Dioxus ergonomic and _familiar_.
|
||||
Our target audience is TypeScript developers looking to switch to Rust for the web—so we need to be comparable to React.
|
||||
Build cool things ✌️
|
||||
@@ -110,7 +110,7 @@ impl<R, S: Storage<SignalData<bool>>> Copy for Comparer<R, S> {}
|
||||
/// use dioxus::prelude::*;
|
||||
/// use dioxus_signals::*;
|
||||
///
|
||||
/// fn App(cx: Scope) -> Element {
|
||||
/// fn App() -> Element {
|
||||
/// let mut count = use_signal(cx, || 0);
|
||||
/// let comparer = use_comparer(cx, move || count.value());
|
||||
///
|
||||
@@ -129,7 +129,7 @@ impl<R, S: Storage<SignalData<bool>>> Copy for Comparer<R, S> {}
|
||||
/// }
|
||||
///
|
||||
/// #[component]
|
||||
/// fn Child(cx: Scope, active: ReadOnlySignal<bool>) -> Element {
|
||||
/// fn Child(active: ReadOnlySignal<bool>) -> Element {
|
||||
/// if *active() {
|
||||
/// render! { "Active" }
|
||||
/// } else {
|
||||
|
||||
Reference in new issue
Block a user