I recently started writing UIs in dioxus and have a big struct that is passed to different components. I do not have full control over that struct as it is from a third-party library. This struct cannot cannot be const
and can therefore not be global. It has to be initiated in main
. A simplified example might look like this:
use dioxus::prelude::*;
#[derive(Props)]
struct BigStructWrapper<'a> {
s: &'a mut BigStruct,
}
#[allow(non_snake_case)]
fn App<'a>(cx: Scope<'a, BigStructWrapper<'a>>) -> Element {
cx.render(rsx! {
div {
// Something with BigStructWrapper/BigStruct
}
})
}
fn main() {
let big_struct = BigStructWrapper {
s: &mut BigStruct::new(),
};
dioxus_desktop::launch(App);
}
I then get the error:
error[E0308]: mismatched types
--> src/main.rs:40:28
|
31 | dioxus_desktop::launch(App);
| ---------------------- ^^^ expected fn pointer, found fn item
| |
| arguments to this function are incorrect
|
= note: expected fn pointer `for<'a> fn(&'a Scoped<'a>) -> Option<VNode<'a>>`
found fn item `for<'a> fn(&'a Scoped<'a, BigStructWrapper<'a>>) -> Option<VNode<'a>> {
Is there a workaround to allow this? Is there a more proper way to do this without a wrapper struct?
I think what you are looking for is described in the Sharing State section of the dioxus documentation. You handle state in dioxus with functions such as use_state
or use_ref
. Here a small example with use_state
where we create the BigStruct
instance in our App
and pass it down to other components:
#![allow(non_snake_case)]
use dioxus::prelude::*;
#[derive(Debug, PartialEq)]
struct BigStruct;
impl BigStruct {
fn new() -> Self {
Self
}
}
fn App(cx: Scope) -> Element {
let big_struct = use_state(cx, || BigStruct::new());
cx.render(rsx! {
Element { bs: big_struct }
})
}
#[inline_props]
fn Element<'a>(cx: Scope, bs: &'a BigStruct) -> Element {
cx.render(rsx! {
div {
"hello {bs:?}"
}
})
}
fn main() {
dioxus_desktop::launch(App);
}