-
In my code, I’m using use_future to handle an async login request. However, I’ve noticed that as soon as the screen renders, the gRPC request to the login function is sent automatically. Could you explain why this happens in Dioxus, and how I can modify my code to prevent the request from being sent on render? Ideally, I want the request to be triggered only when a user action, like a button click, occurs. |
Beta Was this translation helpful? Give feedback.
Replies: 2 comments
-
use crate::BASE_URL;
use dioxus::prelude::*;
use proto::{
authentication_service_client::AuthenticationServiceClient, LoginRequest, LoginResponse,
};
use tonic_web_wasm_client::Client;
use web_sys::{console, wasm_bindgen::JsValue};
pub mod proto {
tonic::include_proto!("user");
}
pub fn Login() -> Element {
let mut login_id = use_signal(|| String::new());
let mut login_password = use_signal(|| String::new());
let mut handleLogin = move || async move {
console::log_1(&JsValue::from("Rendering"));
let data = login(login_id.read().clone(), login_password.read().clone()).await;
data.and_then(|res| {
let local_storage = web_sys::window().unwrap().local_storage().unwrap().unwrap();
let _ = local_storage.set_item("accessToken", &res.access_token);
let _ = local_storage.set_item("refreshToken", &res.refresh_token);
Some(())
});
});
rsx! {
div {
form {
label { id: "id", "ID" }
input {
id: "id",
r#type: "text",
placeholder: "Enter your ID",
onchange: move |evt| {
login_id.set(evt.value().clone());
},
}
label { id: "password", "Password" }
input {
id: "password",
r#type: "password",
placeholder: "Enter your password",
onchange: move |evt| {
login_password.set(evt.value().clone());
},
}
}
}
**button {
onclick: move |evt| {
handleLogin()
},
"Login"
}**
}
}
async fn login(id: String, password: String) -> Option<LoginResponse> {
let mut login_client = AuthenticationServiceClient::new(Client::new(BASE_URL.to_string()));
let response = login_client.login(LoginRequest { id, password }).await;
match response {
Ok(res) => {
let access = res.get_ref().access_token.clone();
let refresh = res.get_ref().refresh_token.clone();
Some(LoginResponse {
access_token: access,
refresh_token: refresh,
})
}
Err(err) => {
console::log_1(&JsValue::from(format!("Login error: {:?}", err)));
return None;
}
}
} |
Beta Was this translation helpful? Give feedback.
-
Thanks to your help, my problem has been solved. Thank you! |
Beta Was this translation helpful? Give feedback.
use_future
always runs when the component is first created. If you want to run a future only when an event is triggered, you can return a future from the event or callspawn
in the event like this: