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

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

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

问题

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

  1. use dioxus::prelude::*;
  2. #[derive(Props)]
  3. struct BigStructWrapper<'a> {
  4. s: &'a mut BigStruct,
  5. }
  6. #[allow(non_snake_case)]
  7. fn App<'a>(cx: Scope<'a, BigStructWrapper<'a>>) -> Element {
  8. cx.render(rsx! {
  9. div {
  10. // 使用BigStructWrapper/BigStruct的一些操作
  11. }
  12. })
  13. }
  14. fn main() {
  15. let big_struct = BigStructWrapper {
  16. s: &mut BigStruct::new(),
  17. };
  18. dioxus_desktop::launch(App);
  19. }

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

  1. error[E0308]: 不匹配的类型
  2. --> src/main.rs:40:28
  3. |
  4. 31 | dioxus_desktop::launch(App);
  5. | ---------------------- ^^^ 预期的函数指针,找到了函数项
  6. | |
  7. | 此函数的参数不正确
  8. |
  9. = 注意:预期的函数指针 `for<'a> fn(&'a Scoped<'a>) -> Option<VNode<'a>>`
  10. 找到函数项 `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:

  1. use dioxus::prelude::*;
  2. #[derive(Props)]
  3. struct BigStructWrapper&lt;&#39;a&gt; {
  4. s: &amp;&#39;a mut BigStruct,
  5. }
  6. #[allow(non_snake_case)]
  7. fn App&lt;&#39;a&gt;(cx: Scope&lt;&#39;a, BigStructWrapper&lt;&#39;a&gt;&gt;) -&gt; Element {
  8. cx.render(rsx! {
  9. div {
  10. // Something with BigStructWrapper/BigStruct
  11. }
  12. })
  13. }
  14. fn main() {
  15. let big_struct = BigStructWrapper {
  16. s: &amp;mut BigStruct::new(),
  17. };
  18. dioxus_desktop::launch(App);
  19. }

I then get the error:

  1. error[E0308]: mismatched types
  2. --&gt; src/main.rs:40:28
  3. |
  4. 31 | dioxus_desktop::launch(App);
  5. | ---------------------- ^^^ expected fn pointer, found fn item
  6. | |
  7. | arguments to this function are incorrect
  8. |
  9. = 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;`
  10. 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:

  1. #![allow(non_snake_case)]
  2. use dioxus::prelude::*;
  3. #[derive(Debug, PartialEq)]
  4. struct BigStruct;
  5. impl BigStruct {
  6. fn new() -&gt; Self {
  7. Self
  8. }
  9. }
  10. fn App(cx: Scope) -&gt; Element {
  11. let big_struct = use_state(cx, || BigStruct::new());
  12. cx.render(rsx! {
  13. Element { bs: big_struct }
  14. })
  15. }
  16. #[inline_props]
  17. fn Element&lt;&#39;a&gt;(cx: Scope, bs: &amp;&#39;a BigStruct) -&gt; Element {
  18. cx.render(rsx! {
  19. div {
  20. &quot;hello {bs:?}&quot;
  21. }
  22. })
  23. }
  24. fn main() {
  25. dioxus_desktop::launch(App);
  26. }
英文:

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:

  1. #![allow(non_snake_case)]
  2. use dioxus::prelude::*;
  3. #[derive(Debug, PartialEq)]
  4. struct BigStruct;
  5. impl BigStruct {
  6. fn new() -&gt; Self {
  7. Self
  8. }
  9. }
  10. fn App(cx: Scope) -&gt; Element {
  11. let big_struct = use_state(cx, || BigStruct::new());
  12. cx.render(rsx! {
  13. Element { bs: big_struct }
  14. })
  15. }
  16. #[inline_props]
  17. fn Element&lt;&#39;a&gt;(cx: Scope, bs: &amp;&#39;a BigStruct) -&gt; Element {
  18. cx.render(rsx! {
  19. div {
  20. &quot;hello {bs:?}&quot;
  21. }
  22. })
  23. }
  24. fn main() {
  25. dioxus_desktop::launch(App);
  26. }

答案2

得分: 1

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

  1. fn main() {
  2. let big_struct = BigStructWrapper {
  3. s: &mut BigStruct::new(),
  4. };
  5. dioxus_desktop::launch_with_props(App, big_struct, Config::new())
  6. }

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

英文:

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

  1. fn main() {
  2. let big_struct = BigStructWrapper {
  3. s: &amp;mut BigStruct::new(),
  4. };
  5. dioxus_desktop::launch_with_props(App, big_struct, Config::new())
  6. }

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:

确定