mirror of
https://github.com/DioxusLabs/dioxus
synced 2024-12-18 08:33:07 +00:00
Merge branch 'master' of https://github.com/DioxusLabs/dioxus into delete-blank-docs
This commit is contained in:
commit
d2c3f98b55
3 changed files with 153 additions and 174 deletions
|
@ -86,7 +86,6 @@ If you know React, then you already know Dioxus.
|
||||||
<th><a href="https://dioxuslabs.com/reference/desktop/">Desktop</a></th>
|
<th><a href="https://dioxuslabs.com/reference/desktop/">Desktop</a></th>
|
||||||
<th><a href="https://dioxuslabs.com/reference/ssr/">SSR</a></th>
|
<th><a href="https://dioxuslabs.com/reference/ssr/">SSR</a></th>
|
||||||
<th><a href="https://dioxuslabs.com/reference/mobile/">Mobile</a></th>
|
<th><a href="https://dioxuslabs.com/reference/mobile/">Mobile</a></th>
|
||||||
<th><a href="https://dioxuslabs.com/guide/concepts/managing_state.html">State</a></th>
|
|
||||||
<tr>
|
<tr>
|
||||||
</table>
|
</table>
|
||||||
|
|
||||||
|
|
|
@ -1,189 +1,172 @@
|
||||||
# Examples
|
# Examples
|
||||||
|
|
||||||
Most of these examples are run through webview so you don't need the Dioxus CLI installed to preview the functionality.
|
These examples are fully-fledged mini Dioxus apps.
|
||||||
|
|
||||||
These examples are fully-fledged micro apps. They can be ran with the `cargo run --example XYZ`
|
You can run them with `cargo run --example EXAMPLE_NAME`. Example:
|
||||||
|
|
||||||
| Example | What it does | Status |
|
```shell
|
||||||
| --------------------------------------------------- | ------------------------------------------- | ------ |
|
cargo run --example hello_world
|
||||||
| [The basics](./basics.rs) | A few basic examples to preview Dioxus | 🛠 |
|
|
||||||
| [fine grained reactivity](./signals.rs) | Escape `diffing` by writing values directly | 🛠 |
|
|
||||||
| [Global State Management](./statemanagement.rs) | Share state between components | 🛠 |
|
|
||||||
| [Virtual Refs]() | Cross-platform imperative elements | 🛠 |
|
|
||||||
| [Inline Styles](./inline-styles.rs) | Define styles for elements inline | 🛠 |
|
|
||||||
| [Conditional Rendering](./conditional-rendering.rs) | Hide/Show elements using conditionals | ✅ |
|
|
||||||
|
|
||||||
These examples are not necessarily meant to be run, but rather serve as a reference for the given functionality.
|
|
||||||
|
|
||||||
| Example | What it does | Status |
|
|
||||||
| --------------------------------------------------- | ----------------------------------------------- | ------ |
|
|
||||||
| [The basics](./basics.rs) | A few basic examples to preview Dioxus | 🛠 |
|
|
||||||
| [fine grained reactivity](./signals.rs) | Escape `diffing` by writing values directly | 🛠 |
|
|
||||||
| [Global State Management](./statemanagement.rs) | Share state between components | 🛠 |
|
|
||||||
| [Virtual Refs]() | Cross-platform imperative elements | 🛠 |
|
|
||||||
| [Inline Styles](./inline-styles.rs) | Define styles for elements inline | 🛠 |
|
|
||||||
| [Conditional Rendering](./conditional-rendering.rs) | Hide/Show elements using conditionals | ✅ |
|
|
||||||
| [Maps/Iterators](./iterators.rs) | Use iterators in the rsx! macro | ✅ |
|
|
||||||
| [Render To string](./tostring.rs) | Render a mounted virtualdom to a string | 🛠 |
|
|
||||||
| [Component Children](./children.rs) | Pass children into child components | 🛠 |
|
|
||||||
| [Function Driven children]() | Pass functions to make VNodes | 🛠 |
|
|
||||||
| [Memoization & Borrowed Data](./memo.rs) | Suppress renders, borrow from parents | ✅ |
|
|
||||||
| [Fragments](./fragments.rs) | Support root-less element groups | ✅ |
|
|
||||||
| [Null/None Components](./empty.rs) | Return nothing! | 🛠 |
|
|
||||||
| [Spread Pattern for props](./spreadpattern.rs) | Manually specify and override props | ✅ |
|
|
||||||
| [Controlled Inputs](./controlled-inputs.rs) | this does | 🛠 |
|
|
||||||
| [Custom Elements]() | Define custom elements | 🛠 |
|
|
||||||
| [Web Components]() | Custom elements to interface with WebComponents | 🛠 |
|
|
||||||
| [Testing And debugging]() | this does | 🛠 |
|
|
||||||
| [Asynchronous Data]() | Using suspense to wait for data | 🛠 |
|
|
||||||
| [Fiber/Scheduled Rendering]() | this does | 🛠 |
|
|
||||||
| [CSS Compiled Styles]() | this does | 🛠 |
|
|
||||||
| [Anti-patterns](./antipatterns.rs) | A collection of discouraged patterns | ✅ |
|
|
||||||
| [Complete rsx reference](./rsx_usage.rs) | A complete reference for all rsx! usage | ✅ |
|
|
||||||
| [Event Listeners](./listener.rs) | Attach closures to events on elements | ✅ |
|
|
||||||
| [Inline Props](./inlineprops.rs) | Using the `#[inline_props]` macro | ✅ |
|
|
||||||
| [Eval](./eval.rs) | Evaluate dynamic JavaScript code | ✅ |
|
|
||||||
|
|
||||||
|
|
||||||
## Show me some examples!
|
|
||||||
|
|
||||||
In our collection of examples, guides, and tutorials, we have:
|
|
||||||
- The book (an introductory course)
|
|
||||||
- The guide (an in-depth analysis of everything in Dioxus)
|
|
||||||
- The reference (a collection of examples with heavy documentation)
|
|
||||||
- The general examples
|
|
||||||
- The platform-specific examples (web, ssr, desktop, mobile, server)
|
|
||||||
|
|
||||||
Here's what a few common tasks look like in Dioxus:
|
|
||||||
|
|
||||||
Nested components with children and internal state:
|
|
||||||
```rust
|
|
||||||
fn App(cx: Scope) -> Element {
|
|
||||||
cx.render(rsx!( Toggle { "Toggle me" } ))
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(PartialEq, Props)]
|
|
||||||
struct ToggleProps { children: Element }
|
|
||||||
|
|
||||||
fn Toggle(cx: Scope<ToggleProps>) -> Element {
|
|
||||||
let mut toggled = use_state(&cx, || false);
|
|
||||||
cx.render(rsx!{
|
|
||||||
div {
|
|
||||||
&cx.props.children
|
|
||||||
button { onclick: move |_| toggled.set(true),
|
|
||||||
toggled.and_then(|| "On").or_else(|| "Off")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
```
|
```
|
||||||
|
|
||||||
Controlled inputs:
|
(Most of these examples are run through webview, so you don't need the Dioxus CLI installed)
|
||||||
```rust
|
|
||||||
fn App(cx: Scope) -> Element {
|
|
||||||
let value = use_state(&cx, String::new);
|
|
||||||
cx.render(rsx!(
|
|
||||||
input {
|
|
||||||
"type": "text",
|
|
||||||
value: "{value}",
|
|
||||||
oninput: move |evt| value.set(evt.value.clone())
|
|
||||||
}
|
|
||||||
))
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
Lists and Conditional rendering:
|
## Basic Features
|
||||||
```rust
|
|
||||||
fn App(cx: Scope) -> Element {
|
|
||||||
let list = (0..10).map(|i| {
|
|
||||||
rsx!(li { key: "{i}", "Value: {i}" })
|
|
||||||
});
|
|
||||||
|
|
||||||
let title = match list.len() {
|
[hello_world](./hello_world.rs) - Most basic example
|
||||||
0 => rsx!("Not enough"),
|
|
||||||
_ => rsx!("Plenty!"),
|
|
||||||
};
|
|
||||||
|
|
||||||
if should_show {
|
[readme](./readme.rs) - Counter example from the Readme
|
||||||
cx.render(rsx!(
|
|
||||||
title,
|
|
||||||
ul { list }
|
|
||||||
))
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
Tiny components:
|
[custom_assets](./custom_assets.rs) - Include images
|
||||||
```rust
|
|
||||||
static App: Component = |cx| rsx!(cx, div {"hello world!"});
|
|
||||||
```
|
|
||||||
|
|
||||||
Borrowed prop contents:
|
[custom_element](./custom_element.rs) - Render webcomponents
|
||||||
```rust
|
|
||||||
fn App(cx: Scope) -> Element {
|
|
||||||
let name = use_state(&cx, || String::from("example"));
|
|
||||||
rsx!(cx, Child { title: name.as_str() })
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Props)]
|
[custom_html](./custom_html.rs) - Customize wrapper HTML
|
||||||
struct ChildProps<'a> { title: &'a str }
|
|
||||||
|
|
||||||
fn Child(cx: Scope<ChildProps>) -> Element {
|
[eval](./eval.rs) - Evaluate JS expressions
|
||||||
rsx!(cx, "Hello {cx.props.title}")
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
Global State
|
### RSX
|
||||||
```rust
|
|
||||||
struct GlobalState { name: String }
|
|
||||||
|
|
||||||
fn App(cx: Scope) -> Element {
|
[rsx_usage](./rsx_usage.rs) - Demo of all RSX features
|
||||||
use_provide_shared_state(cx, || GlobalState { name: String::from("Toby") })
|
|
||||||
rsx!(cx, Leaf {})
|
|
||||||
}
|
|
||||||
|
|
||||||
fn Leaf(cx: Scope) -> Element {
|
[xss_safety](./xss_safety.rs) - You can include text without worrying about injections by default
|
||||||
let state = use_consume_shared_state::<GlobalState>(cx)?;
|
|
||||||
rsx!(cx, "Hello {state.name}")
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
Router (inspired by Yew-Router)
|
### Props
|
||||||
```rust
|
|
||||||
#[derive(PartialEq, Clone, Hash, Eq, Routable)]
|
|
||||||
enum Route {
|
|
||||||
#[at("/")]
|
|
||||||
Home,
|
|
||||||
#[at("/post/{id}")]
|
|
||||||
Post(id)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn App(cx: Scope) -> Element {
|
[borrowed](./borrowed.rs) - Borrowed props
|
||||||
let route = use_router(cx, Route::parse);
|
|
||||||
cx.render(rsx!(div {
|
|
||||||
match route {
|
|
||||||
Route::Home => rsx!( Home {} ),
|
|
||||||
Route::Post(id) => rsx!( Post { id: id })
|
|
||||||
}
|
|
||||||
}))
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
Suspense
|
[inlineprops](./inlineprops.rs) - Demo of `inline_props` macro
|
||||||
```rust
|
|
||||||
fn App(cx: Scope) -> Element {
|
|
||||||
let doggo = use_suspense(cx,
|
|
||||||
|| async { reqwest::get("https://dog.ceo/api/breeds/image/random").await.unwrap().json::<Response>().await.unwrap() },
|
|
||||||
|response| cx.render(rsx!( img { src: "{response.message}" }))
|
|
||||||
);
|
|
||||||
|
|
||||||
cx.render(rsx!{
|
[optional_props](./optional_props.rs) - Optional props
|
||||||
div {
|
|
||||||
"One doggo coming right up:",
|
### CSS
|
||||||
doggo
|
|
||||||
}
|
[all_css](./all_css.rs) - You can specify any CSS attribute
|
||||||
})
|
|
||||||
}
|
[tailwind](./tailwind.rs) - You can use a library for styling
|
||||||
```
|
|
||||||
|
## Input Handling
|
||||||
|
|
||||||
|
[all_events](./all_events.rs) - Basic event handling demo
|
||||||
|
|
||||||
|
[filedragdrop](./filedragdrop.rs) - Handle dropped files
|
||||||
|
|
||||||
|
[form](./form.rs) - Handle form submission
|
||||||
|
|
||||||
|
[inputs](./inputs.rs) - Input values
|
||||||
|
|
||||||
|
[nested_listeners](./nested_listeners.rs) - Nested handlers and bubbling
|
||||||
|
|
||||||
|
[textarea](textarea.rs) - Text area input
|
||||||
|
|
||||||
|
### State Management
|
||||||
|
|
||||||
|
[fermi](./fermi.rs) - Fermi library for state management
|
||||||
|
|
||||||
|
[pattern_reducer](./pattern_reducer.rs) - The reducer pattern with `use_state`
|
||||||
|
|
||||||
|
[rsx_compile_fail](./rsx_compile_fail.rs)
|
||||||
|
|
||||||
|
### Async
|
||||||
|
|
||||||
|
[login_form](./login_form.rs) - Login endpoint example
|
||||||
|
|
||||||
|
[suspense](./suspense.rs) - Render placeholders while data is loading
|
||||||
|
|
||||||
|
[tasks](./tasks.rs) - Continuously run future
|
||||||
|
|
||||||
|
[order](./order.rs)
|
||||||
|
|
||||||
|
### SVG
|
||||||
|
|
||||||
|
[svg_basic](./svg_basic.rs)
|
||||||
|
|
||||||
|
[svg](./svg.rs)
|
||||||
|
|
||||||
|
### Performance
|
||||||
|
|
||||||
|
[framework_benchmark](./framework_benchmark.rs) - Renders a huge list
|
||||||
|
|
||||||
|
[heavy_compute](./heavy_compute.rs) - How to deal with expensive operations
|
||||||
|
|
||||||
|
## Server-side rendering
|
||||||
|
|
||||||
|
[ssr](./ssr.rs) - Rendering RSX server-side
|
||||||
|
|
||||||
|
[hydration](./hydration.rs) - Pre-rendering with hydration
|
||||||
|
|
||||||
|
## Common Patterns
|
||||||
|
|
||||||
|
[disabled](./disabled.rs) - Disable buttons conditionally
|
||||||
|
|
||||||
|
[error_handle](./error_handle.rs) - Handle errors with early return
|
||||||
|
|
||||||
|
## Routing
|
||||||
|
|
||||||
|
[flat_router](./flat_router.rs) - Basic, flat route example
|
||||||
|
|
||||||
|
[router](./router.rs) - Router example
|
||||||
|
|
||||||
|
[link](./link.rs) - Internal, external and custom links
|
||||||
|
|
||||||
|
## Platform Features
|
||||||
|
|
||||||
|
[window_event](./window_event.rs) - Window decorations, fullscreen, minimization, etc.
|
||||||
|
|
||||||
|
[window_zoom](./window_zoom.rs) – Zoom in or out
|
||||||
|
|
||||||
|
## Example Apps
|
||||||
|
|
||||||
|
[calculator](./calculator.rs) - Simple calculator
|
||||||
|
|
||||||
|
[pattern_model](./pattern_model.rs) - Simple calculator, but using a custom struct as the model
|
||||||
|
|
||||||
|
[crm](./crm.rs) - Toy multi-page customer management app
|
||||||
|
|
||||||
|
[dog_app](./dog_app.rs) - Accesses dog API
|
||||||
|
|
||||||
|
[file_explorer](./file_explorer.rs) - File browser that uses `use_ref` to interact with the model
|
||||||
|
|
||||||
|
[todomvc](./todomvc.rs) - Todo task list example
|
||||||
|
|
||||||
|
## Terminal UI
|
||||||
|
|
||||||
|
[tui_border](./tui_border.rs)
|
||||||
|
|
||||||
|
[tui_buttons](./tui_buttons.rs)
|
||||||
|
|
||||||
|
[tui_color_test](./tui_color_test.rs)
|
||||||
|
|
||||||
|
[tui_components](./tui_components.rs)
|
||||||
|
|
||||||
|
[tui_frame](./tui_frame.rs)
|
||||||
|
|
||||||
|
[tui_hover](./tui_hover.rs)
|
||||||
|
|
||||||
|
[tui_keys](./tui_keys.rs)
|
||||||
|
|
||||||
|
[tui_list](./tui_list.rs)
|
||||||
|
|
||||||
|
[tui_margin](./tui_margin.rs)
|
||||||
|
|
||||||
|
[tui_quadrants](./tui_quadrants.rs)
|
||||||
|
|
||||||
|
[tui_readme](./tui_readme.rs)
|
||||||
|
|
||||||
|
[tui_task](./tui_task.rs)
|
||||||
|
|
||||||
|
[tui_text](./tui_text.rs)
|
||||||
|
|
||||||
|
# TODO
|
||||||
|
Missing Features
|
||||||
|
- Fine-grained reactivity
|
||||||
|
- Refs - imperative handles to elements
|
||||||
|
- Function-driven children: Pass functions to make VNodes
|
||||||
|
|
||||||
|
Missing examples
|
||||||
|
- Shared state
|
||||||
|
- Root-less element groups
|
||||||
|
- Spread props
|
||||||
|
- Custom elements
|
||||||
|
- Component Children: Pass children into child components
|
||||||
|
- Render To string: Render a mounted virtualdom to a string
|
||||||
|
- Testing and Debugging
|
|
@ -835,10 +835,7 @@ impl ScopeState {
|
||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
#[allow(clippy::mut_from_ref)]
|
#[allow(clippy::mut_from_ref)]
|
||||||
pub fn use_hook<'src, State: 'static>(
|
pub fn use_hook<State: 'static>(&self, initializer: impl FnOnce(usize) -> State) -> &mut State {
|
||||||
&'src self,
|
|
||||||
initializer: impl FnOnce(usize) -> State,
|
|
||||||
) -> &'src mut State {
|
|
||||||
let mut vals = self.hook_vals.borrow_mut();
|
let mut vals = self.hook_vals.borrow_mut();
|
||||||
|
|
||||||
let hook_len = vals.len();
|
let hook_len = vals.len();
|
||||||
|
|
Loading…
Reference in a new issue