I am building a Yew manga reader application. The home page is a bookshelf that contains thumbnails, and clicking on the thumbnails brings me to a page rendering the pages of the book.
fn switch(routes: Route) -> Html {
match routes {
Route::Home => html! {
<>
<h1>{ "Books" }</h1>
<BookShelf />
</>
},
Route::BookContent { name } => html! {
<div>
<BookContent name={name} />
</div>
},
Route::NotFound => html! { <div>{ "You sure that book exist?" }</div> },
}
}
#[function_component]
fn App() -> Html {
html! {
<HashRouter>
<Switch<Route> render={switch} />
</HashRouter>
}
}
The BookShelf gets a list of books I have, fetches the thumbnails individually to render in 2 columns.
#[styled_component]
fn BookShelf() -> Html {
let books = use_state(|| vec![]);
{
let books = books.clone();
use_effect_with((), move |_| {
let books = books.clone();
wasm_bindgen_futures::spawn_local(async move {
let url = format!("{}/books", BACKEND_URL);
let fetched_books: Vec<String> = Request::get(&url)
.send()
.await
.unwrap()
.json()
.await
.unwrap();
books.set(fetched_books);
});
})
}
html! {
<>
{
for books.chunks(2).map(|books| html! {
<div class={css!("display:flex;")}>
{
books.iter().map(|book| html! {
<div class={css!("flex:50%;")}>
<Book name={book.clone()}/>
</div>
}).collect::<Html>()
}
</div>
})
}
</>
}
}
The Book component actually fetches the thumbnail using use_effect_with(). It also switches route to Route::BookContent when it is clicked.
BookContent is similar to BookShelf except it fetches and renders the images in the same column.
The current behaviour of the page is that when I click a thumbnail before all thumbnails are fetched and loaded, it goes to the BookContent page, but it waits all the pending thumbnail GET requests to complete before fetching the book content.
How can I abort all pending get request after the Route::Home component disappears (aka clicking a thumbnail to go to Route::BookContent) so that I can immediately start fetching the book content?
Edit
I just came across Theo's video "You Need React Query Now More Than Ever", which mentions you can send signal to useQuery and abort the query. I am thinking this may be want I need, to early return the callback if route is changed. Probably using a combination of context and use_location / use_route?
So actually the future that I should be aborting is
gloo_net::http::Requestnotwasm_bindgen_futures::spwan_localbecause the wasm future gets dispatched immediately what it is rendered and it is theRequestthat is awaiting. And luckily there is an abort mechanism ingloo_net::http::Requestby settingAbortSignal.By making use of the fact that
use_effect_with()calls its return value to cleanup when a component is destroyed, we can abortRequestwhenImagecomponent gets out of scope.Note that if you renders an image with
The
GETrequest dispatched byimgtag won't be aborted even when the component is destroyed.