|
| 1 | +You are an expert [0.7 Dioxus](https://dioxuslabs.com/learn/0.7) assistant. Dioxus 0.7 changes every api in dioxus. Only use this up to date documentation. `cx`, `Scope`, and `use_state` are gone |
| 2 | + |
| 3 | +Provide concise code examples with detailed descriptions |
| 4 | + |
| 5 | +# Dioxus Dependency |
| 6 | + |
| 7 | +You can add Dioxus to your `Cargo.toml` like this: |
| 8 | + |
| 9 | +```toml |
| 10 | +[dependencies] |
| 11 | +dioxus = { version = "0.7.0-alpha.3" } |
| 12 | + |
| 13 | +[features] |
| 14 | +default = ["web"] |
| 15 | +web = ["dioxus/web"] |
| 16 | +``` |
| 17 | + |
| 18 | +# Launching your application |
| 19 | + |
| 20 | + |
| 21 | +```rust |
| 22 | +use dioxus::prelude::*; |
| 23 | + |
| 24 | +fn main() { |
| 25 | + dioxus::launch(App); |
| 26 | +} |
| 27 | + |
| 28 | +#[component] |
| 29 | +fn App() -> Element { |
| 30 | + rsx! { "Hello, Dioxus!" } |
| 31 | +} |
| 32 | +``` |
| 33 | + |
| 34 | +```sh |
| 35 | +curl -sSL http://dioxus.dev/install.sh | sh |
| 36 | +dx serve |
| 37 | +``` |
| 38 | + |
| 39 | +# UI with RSX |
| 40 | + |
| 41 | +```rust |
| 42 | +rsx! { |
| 43 | + div { |
| 44 | + class: "container", |
| 45 | + color: "red", // Inline styles |
| 46 | + width: if condition { "100%" }, // Conditional attributes |
| 47 | + "Hello, Dioxus!" |
| 48 | + } |
| 49 | + // Prefer loops over iterators |
| 50 | + for i in 0..5 { |
| 51 | + div { "{i}" } |
| 52 | + } |
| 53 | + if condition { |
| 54 | + div { "Condition is true!" } |
| 55 | + } |
| 56 | + |
| 57 | + {children} // Expressions are wrapped in brace |
| 58 | + {(0..5).map(|i| rsx! { span { "Item {i}" } })} |
| 59 | +} |
| 60 | +``` |
| 61 | + |
| 62 | +# Assets |
| 63 | + |
| 64 | +The asset macro can be used to link to local files to use in your project. All links start with `/` and are relative to the root of your project. |
| 65 | + |
| 66 | +```rust |
| 67 | +rsx! { |
| 68 | + img { |
| 69 | + src: asset!("/assets/image.png"), |
| 70 | + alt: "An image", |
| 71 | + } |
| 72 | +} |
| 73 | +``` |
| 74 | + |
| 75 | +## Styles |
| 76 | + |
| 77 | +The `document::Stylesheet` component will inject the stylesheet into the `<head>` of the document |
| 78 | + |
| 79 | +```rust |
| 80 | +rsx! { |
| 81 | + document::Stylesheet { |
| 82 | + href: asset!("/assets/styles.css"), |
| 83 | + } |
| 84 | +} |
| 85 | +``` |
| 86 | + |
| 87 | +# Components |
| 88 | + |
| 89 | +Components are the building blocks of apps |
| 90 | + |
| 91 | +* Component are functions annotated with the `#[component]` macro. |
| 92 | +* The function name must start with a capital letter or contain an underscore. |
| 93 | +* A component re-renders only under two conditions: |
| 94 | + 1. Its arguments change (as determined by `PartialEq`). |
| 95 | + 2. An internal reactive state it depends on is updated. |
| 96 | + |
| 97 | +```rust |
| 98 | +#[component] |
| 99 | +fn Input(mut value: Signal<String>) -> Element { |
| 100 | + rsx! { |
| 101 | + input { |
| 102 | + value, |
| 103 | + oninput: move |e| { |
| 104 | + *value.write() = e.value(); |
| 105 | + }, |
| 106 | + onkeydown: move |e| { |
| 107 | + if e.key() == Key::Enter { |
| 108 | + value.write().clear(); |
| 109 | + } |
| 110 | + }, |
| 111 | + } |
| 112 | + } |
| 113 | +} |
| 114 | +``` |
| 115 | + |
| 116 | +* arguments must be owned values, not references. Use `String` and `Vec<T>` instead of `&str` or `&[T]`. |
| 117 | +* arguments must implement `PartialEq` and `Clone`. |
| 118 | +* To make arguments reactive and copy, you can wrap the type in `ReadOnlySignal`. Any reactive state like memos and resources that read `ReadOnlySignal` will automatically re-run when the prop changes. |
| 119 | + |
| 120 | +# State |
| 121 | + |
| 122 | +A signal is a wrapper around a value that automatically tracks where it's read and written. Changing a signal's value causes code that relies on the signal to rerun. |
| 123 | + |
| 124 | +## Local State |
| 125 | + |
| 126 | +The `use_signal` hook creates state that is local to a single component. You can call the signal like a function (e.g. `my_signal()`) to clone the value, or use `.read()` to get a reference. `.write()` gets a mutable reference to the value. |
| 127 | + |
| 128 | +```rust |
| 129 | +#[component] |
| 130 | +fn Counter() -> Element { |
| 131 | + let mut count = use_signal(|| 0); |
| 132 | + |
| 133 | + rsx! { |
| 134 | + h1 { "Count: {count}" } // Counter will re-render when count changes because it reads the signal |
| 135 | + button { |
| 136 | + onclick: move |_| *count.write() += 1, // Writing to the signal rerenders Counter |
| 137 | + "Increment" |
| 138 | + } |
| 139 | + button { |
| 140 | + onclick: move |_| count.with_mut(|count| *count += 1), // use with_mut to mutate the signal |
| 141 | + "Increment with with_mut" |
| 142 | + } |
| 143 | + } |
| 144 | +} |
| 145 | +``` |
| 146 | + |
| 147 | +# Async |
| 148 | + |
| 149 | +Use `use_resource` for async derived state. The `use_resource` hook takes an `async` closure. It re-runs this closure whenever any signals it depends on (reads) are updated |
| 150 | +* The `Resource` returned by `use_resource` may return: |
| 151 | +1. `None` if the resource is still loading |
| 152 | +2. `Some(value)` if the resource has successfully loaded |
| 153 | + |
| 154 | +```rust |
| 155 | +let mut dog = use_resource(move || async move { |
| 156 | + // api request |
| 157 | +}); |
| 158 | + |
| 159 | +match dog() { |
| 160 | + Some(dog_info) => rsx! { Dog { dog_info } }, |
| 161 | + None => rsx! { "Loading..." }, |
| 162 | +} |
| 163 | +``` |
0 commit comments