Search code examples
rustyew

How to return string value of state in hook?


Returning string state in use_effect_with_deps gives error.

use std::ops::Deref;
use yew::prelude::*;


#[hook]
pub fn use_hook_test() -> String
{
    let first_load = use_state(|| true);

    let hash_state = use_state(|| "".to_owned());

 
    let hash_state_clone = hash_state.clone();
    use_effect_with_deps(move |_| {
        if *first_load {
            wasm_bindgen_futures::spawn_local(async move {

                    hash_state_clone.set(format!("{:?}", "Hello"));
                
            });

            first_load.set(false);
        }
        || {};
    }, ());

    hash_state_clone.deref().clone()
}

Error:

let hash_state_clone = hash_state.clone();
   |         ---------------- move occurs because `hash_state_clone` has type `yew::UseStateHandle<std::string::String>`, which does not implement the `Copy` trait
14 |     use_effect_with_deps(move |_| {
   |                          -------- value moved into closure here
...
18 |                     hash_state_clone.set(format!("{:?}", "Hello"));
   |                     ---------------- variable moved due to use in closure
...
27 |     hash_state_clone.deref().clone()
   |     ^^^^^^^^^^^^^^^^^^^^^^^^ value borrowed here after move

Solution

  • Here is a Yew Playground based on your example with some minor changes:

    • added an explicit scope to isolate the use_effect_with_deps
    • added a second hash_state.clone() after that scope

    The result is somewhat nonsensical but compiles ok.

    #[hook]
    pub fn use_hook_test() -> String
    {
        let first_load = use_state(|| true);
        let hash_state = use_state(|| "".to_owned());
        {
            let hash_state_clone = hash_state.clone();
            use_effect_with_deps(move |_| {
                if *first_load {
                    wasm_bindgen_futures::spawn_local(async move {
                        hash_state_clone.set(format!("{:?}", "Hello"));
                    });
                    first_load.set(false);
                }
                || {};
            }, ());
        }
    
        let hash_state_clone = hash_state.clone();
        hash_state_clone.deref().clone()
    }