yew icon indicating copy to clipboard operation
yew copied to clipboard

[Feature]: Provide a `Default` trait implementation for the `UseStateHandle` struct

Open wiseaidev opened this issue 1 year ago • 2 comments

Problem:

While working on yew-alert, I noticed that std::default::Default is not implemented for yew::UseStateHandle. This could be beneficial when implementing the Default trait for a component's Props. For instance, in the case of AlertProps, it would resemble:

impl Default for AlertProps {
    fn default() -> Self {
        AlertProps {
            message: Default::default(),
            timeout: Default::default(),
            show_alert: Default::default(), // Error: the trait `std::default::Default` is not implemented for `yew::UseStateHandle<bool>`
            // show_alert: use_state(|| true), // <--- This thing should work, but it is returning opaque type something
            // ...snip...
        }
    }
}

This functionality is useful for allowing users to initialize the props struct by only passing some of the props values, with the others set to default, like so:

let props = AlertProps {
    message: "Hello",
    ..AlertProps::default()
}

And then consume it in a component like so:

html!{
    <Alert ..props />
}

The same should apply to the prop_or attribute:

pub struct AlertProps {
    // ...snip...
    /// State handle to control the visibility of the alert.
    #[prop_or(use_state(|| true)]
    pub show_alert: UseStateHandle<bool>,
    // ...snip...
html!{
    <Alert message="Hello" />
}

Steps To Reproduce:

Attempt to implement Default for props containing a UseStateHandle field type.

Expected Behavior:

The UseStateHandle struct should have an implementation of the Default trait.

Environment:

  • Yew version: 0.21.0
  • Rust version: 1.75.0
  • Target: wasm32-unknown-unknown
  • Build Tool: trunk
  • OS: Any
  • Browser and Version: Any

Questionnaire:

  • [ ] I'm interested in fixing this myself but don't know where to start
  • [ ] I would like to fix it and I have a solution
  • [X] I don't have time to fix this right now, but maybe later

[!NOTE] This feature is useful to adhere to the DRY principle and decouple logic from UI as shown in this example.

wiseaidev avatar Feb 03 '24 19:02 wiseaidev

This seems like a nice first issue, im open to picking this up if you guys agree. Will probably require some generics and working with traits but am open to the challenge

dospore avatar Feb 04 '24 22:02 dospore

@wiseaidev after having a look it seems pretty complex. We could make it work by giving an empty closure as the dispatch function but would not achieve much since you can just do that on your side instead and pass a default show_alert closure instead of a UseStateHandler. The opaque type comes from the hook macro which allows the reducers to access the HookContext which gets created when the function component is created. Since this is props im not sure that can be instantiated before then and is why hooks must be called inside the fc.

The usecase might not be important enough for its complexity (if it is complex). It feels like there might be a way to do it but will have to wait for more guidance from someone a bit more experience with the codebase.

dospore avatar Feb 06 '24 01:02 dospore