Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Open
DioxusGrow opened this issue Sep 18, 2024 · 2 comments

Comments

@DioxusGrow
Copy link

DioxusGrow commented Sep 18, 2024

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
@DioxusGrow DioxusGrow changed the title New Syntax Prevents Initial State Activation Without Breaking Hook Rules The new syntax does not allow you to create an initial state without violating the hook creation rules Sep 18, 2024
@matthunz
Copy link
Contributor

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

@DioxusGrow
Copy link
Author

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants