DioxusLabs / dioxus

Fullstack app framework for web, desktop, mobile, and more.
https://dioxuslabs.com
Apache License 2.0
21.44k stars 826 forks source link

[solved, needs review] Can't launch with props (web) #2496

Closed fr-an-k closed 5 months ago

fr-an-k commented 5 months ago

Problem

I can't figure out from the docs or examples (or the repo) how to pass props to the root component when launching.

Some outdated documentation (https://dioxuslabs.com/docs/nightly/guide/en/fullstack/server_functions.html) mentions dioxus_web::launch_with_props, but this function doesn't exist (anymore).

The ecommerce example uses this function on the liveview platform.

I also tried to make a closure-based component but that doesn't seem to be possible due to the lack of dyn in the component fn parameter type.

Steps To Reproduce Something like this:

use dioxus::prelude::*;
use wasm_bindgen::prelude::*;

#[derive(Debug, PartialEq, Clone, Props)]
struct AppProps {
  name: String,
}

#[component]
fn App(props: AppProps) -> Element {
  rsx! (
    button {
      onclick: move |e| info!("clicked {}", state.name)
      "Click me"
    }
  )
}

// Allow creating multiple Dioxus windows in an existing (React) website
#[wasm_bindgen]
pub fn create_my_root_component(id: &str) {
  let window = web_sys::window().unwrap();
  let document = window.document().unwrap();
  let val = document
    .get_element_by_id(id)
    .unwrap()
    .dyn_into::<web_sys::HtmlElement>()
    .unwrap();
  let cfg = dioxus_web::Config::new().rootname(id);
  dioxus_web::launch_with_props(App, AppProps { name: id.into() }, cfg);
  //This worked but without props in App:
  //dioxus_web::launch::launch_cfg(App, cfg);
  //A more idiomatic way might be to use dioxus::launch::LaunchBuilder but this is also not yet documented
}

Add dioxus_web as a dependency.

Build:

wasm-pack build --target web

Environment:

Questionnaire

fr-an-k commented 5 months ago

I solved it by using a manual root virtual dom:

let vdom = VirtualDom::new_with_props(App, AppProps { name: id.into() });
dioxus_web::launch::launch_virtual_dom(vdom, cfg);

Dynamic rendering works properly. Might want to improve the API/documentation, otherwise this can be closed.

ealmloff commented 5 months ago

Instead of using root props, you can provide root context with the launch builder