有没有办法将一个属性传递给dioxus中的主组件?

huangapple go评论67阅读模式
英文:

Is there a way to pass a prop to the main component in dioxus?

问题

最近我开始在dioxus中编写UI,并有一个大的结构体传递给不同的组件。我无法完全控制这个结构体,因为它来自第三方库。这个结构体不能是const,因此不能是全局的。它必须在main中初始化。一个简化的示例可能如下所示:

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 {
            // 使用BigStructWrapper/BigStruct的一些操作
        }
    })
}

fn main() {
    let big_struct = BigStructWrapper {
        s: &mut BigStruct::new(),
    };

    dioxus_desktop::launch(App);
}

然后我收到以下错误信息:

error[E0308]: 不匹配的类型
  --> src/main.rs:40:28
   |
31 |     dioxus_desktop::launch(App);
   |     ---------------------- ^^^ 预期的函数指针,找到了函数项
   |     |
   |     此函数的参数不正确
   |
   = 注意:预期的函数指针 `for<'a> fn(&'a Scoped<'a>) -> Option<VNode<'a>>`
                 找到函数项 `for<'a> fn(&'a Scoped<'a>, BigStructWrapper<'a>) -> Option<VNode<'a>> {

是否有一种解决方法可以允许这样做?是否有一种更合适的方法来做到这一点,而不需要一个包装结构体?

英文:

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&lt;&#39;a&gt; {
    s: &amp;&#39;a mut BigStruct,
}

#[allow(non_snake_case)]
fn App&lt;&#39;a&gt;(cx: Scope&lt;&#39;a, BigStructWrapper&lt;&#39;a&gt;&gt;) -&gt; Element {
    cx.render(rsx! {
        div {
            // Something with BigStructWrapper/BigStruct
        }
    })
}

fn main() {
    let big_struct = BigStructWrapper {
        s: &amp;mut BigStruct::new(),
    };

    dioxus_desktop::launch(App);
}

I then get the error:

error[E0308]: mismatched types
  --&gt; 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&lt;&#39;a&gt; fn(&amp;&#39;a Scoped&lt;&#39;a&gt;) -&gt; Option&lt;VNode&lt;&#39;a&gt;&gt;`
                 found fn item `for&lt;&#39;a&gt; fn(&amp;&#39;a Scoped&lt;&#39;a, BigStructWrapper&lt;&#39;a&gt;&gt;) -&gt; Option&lt;VNode&lt;&#39;a&gt;&gt; {

Is there a workaround to allow this? Is there a more proper way to do this without a wrapper struct?

答案1

得分: 2

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() -&gt; Self {
        Self
    }
}

fn App(cx: Scope) -&gt; Element {
    let big_struct = use_state(cx, || BigStruct::new());

    cx.render(rsx! {
        Element { bs: big_struct }
    })
}

#[inline_props]
fn Element&lt;&#39;a&gt;(cx: Scope, bs: &amp;&#39;a BigStruct) -&gt; Element {
    cx.render(rsx! {
      div {
        &quot;hello {bs:?}&quot;
      }
    })
}

fn main() {
    dioxus_desktop::launch(App);
}
英文:

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() -&gt; Self {
        Self
    }
}

fn App(cx: Scope) -&gt; Element {
    let big_struct = use_state(cx, || BigStruct::new());

    cx.render(rsx! {
        Element { bs: big_struct }
    })
}

#[inline_props]
fn Element&lt;&#39;a&gt;(cx: Scope, bs: &amp;&#39;a BigStruct) -&gt; Element {
    cx.render(rsx! {
      div {
        &quot;hello {bs:?}&quot;
      }
    })
}

fn main() {
    dioxus_desktop::launch(App);
}

答案2

得分: 1

你还可以尝试通过launch_with_props()直接传递结构体到main函数中:

fn main() {
    let big_struct = BigStructWrapper {
        s: &mut BigStruct::new(),
    };

    dioxus_desktop::launch_with_props(App, big_struct, Config::new())
}

从那里,你应该能够通过cx.props.s在组件中访问它。

英文:

You can also try passing the struct directly over main by using launch_with_props():

fn main() {
    let big_struct = BigStructWrapper {
        s: &amp;mut BigStruct::new(),
    };

    dioxus_desktop::launch_with_props(App, big_struct, Config::new())
}

From there, you should be able to access it in the component thru cx.props.s.

huangapple
  • 本文由 发表于 2023年2月27日 01:51:22
  • 转载请务必保留本文链接:https://go.coder-hub.com/75573936.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定