Last active
June 16, 2023 03:39
-
-
Save echochamber/74ddc7511a7e199f11779b6483c84380 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// My component which I render. | |
pub fn Component(cx: Scope) -> Element { | |
let (form, display) = InitFormAndDisplay(cx); | |
cx.render(rsx!{ | |
form | |
div { hr {} } | |
display | |
}) | |
} | |
// Get a handle to both the form and the display elements, which both are using the | |
// search_result shared state handle to communicate updates. | |
pub fn InitFormAndDisplay (cx: Scope) -> (Element, Element) { | |
// Shared state between the form and the display. | |
let search_result: &UseState<Option<ApiResult>> = use_state(cx, || None); | |
let search = move |evt: FormEvent| { | |
// cx.spawn here is only necessary because I want to call an external API with the form content, | |
// if you just want to do regular form handling stuff, you can do it here without spawning an | |
// async task using cx.spawn. | |
cx.spawn({ | |
// Do stuff with the result from the event. | |
let qString = evt.values["query"].clone(); | |
// Need to do this before enter async block to avoid moved error from borrow checker. | |
let search_result = search_result.to_owned(); | |
async move { | |
// Me Calling some external API | |
let resp = SomeService::new().query(&qString.as_str()).await; | |
// Handling response from API and Setting relevant data from api in shared state. | |
match &resp { | |
Ok(_data) => debug!("Query successful!") | |
Err(_err) => debug!("Query failed") | |
} | |
search_result.set(Some(resp)); | |
} | |
}); | |
}; | |
( | |
cx.render(rsx! { | |
SearchForm {on_submit: move |evt: FormEvent| { search(evt) } } | |
}), | |
cx.render(rsx! { | |
SearchDisplay { search_result: &search_result } | |
}) | |
) | |
} | |
#[inline_props] | |
pub fn SearchForm<'a> (cx: Scope, on_submit: EventHandler<'a, FormEvent>) -> Element<'a> { | |
cx.render(rsx! { | |
form { | |
prevent_default: "onsubmit", | |
onsubmit: move |event| on_submit.call(event), | |
input { id: "query", name: "query", } | |
button { | |
value: "Submit", | |
r#type: "submit", | |
prevent_default: true, | |
"Search", | |
} | |
} | |
}) | |
} | |
#[inline_props] | |
pub fn SearchDisplay<'a> (cx: Scope<'a>, search_result: &'a UseState<Option<Result>>) -> Element<'a> { | |
cx.render(match search_result.get() { | |
// You can just do regular rsx here, I'm matching because I need to handle the result of my API | |
// call from above | |
Some(Ok(response)) => { | |
// API call is done, render results | |
e @ Some(Err(_)) => { | |
// API Call is done and errored. Render error | |
} | |
_ => rsx! { | |
// Waiting for API call to finish, show loading indicator. | |
}, | |
}) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment