dioxus icon indicating copy to clipboard operation
dioxus copied to clipboard

The new syntax does not allow you to create an initial state without violating the hook creation rules

Open RustGrow opened this issue 1 year ago • 2 comments

The new 0.6 syntax makes it impossible to activate the initial state of an application without breaking the rules for using hooks. Using the 0.5 application initial syntax, use_context_provider initializes the creation of the initial application state inside the function:

fn App() -> Element {
    use_context_provider(|| Signal::new("en".to_string()))
}

The new syntax is like a street with two red lights on it, where you can’t initialize state without breaking the hook rules, because launch is a closure and causes a hook error.

fn main () {
use_context_provider(|| Signal::new("en".to_string()))
launch(|| {
    rsx! {
        // Your component code here
    }
});
}

Has an error: hook called outside component or hook

launch(|| {
    use_context_provider(|| Signal::new("en".to_string()))
    rsx! {
        // Your component code here
    }
});

Has an errors hook called in a closure and hook called outside component or hook

Environment:

  • Dioxus version: 0.6 from git
  • Rust version: rustc 1.81.0
  • OS info: win11
  • App platform: web

RustGrow avatar Sep 18 '24 10:09 RustGrow

Would something like this work for you?

fn main () {
  // If you need to load from env vars or etc
  let locale = String::from("en");
  
  launch(move || {
    rsx! {
      App { locale: locale.clone() }
    }
  });
}

#[component]
fn App(locale: String) {
  use_context_provider(|| Signal::new(locale))
  
  // Your component code here
}

GlobalSignal might also fit your use case

matthunz avatar Sep 18 '24 21:09 matthunz

It's the same thing

fn main() {
    dioxus_logger::init(Level::INFO).expect("failed to init logger");
    info!("starting app");
    launch(App);
}

fn App() -> Element {
    use_context_provider(|| Signal::new("en".to_string()));
    let mut lang: Signal<String> = use_context();

The new syntax replaces the code above

fn main() {   
    launch(|| {
        use_context_provider(|| Signal::new("en".to_string()));
        rsx! {}
    });
}

Evan says it's fine and the rules are not broken, but because the app is not directly defined as a component. dx check will constantly generate a signals violation error image

RustGrow avatar Sep 19 '24 16:09 RustGrow