Skip to content

Commit 5aeaa6a

Browse files
authored
fix: Bug fixes and code cleanup (#21)
* fix: Bug fixes and code cleanup * chore: bump to v0.5.1
1 parent 3dacfc0 commit 5aeaa6a

File tree

2 files changed

+60
-71
lines changed

2 files changed

+60
-71
lines changed

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
[package]
22
name = "dioxus-query"
33
description = "Fully-typed, async, reusable cached state management for Dioxus 🧬"
4-
version = "0.5.0"
4+
version = "0.5.1"
55
edition = "2021"
66
license = "MIT"
77
authors = ["Marc Espín <[email protected]>"]

src/use_query.rs

Lines changed: 59 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -62,20 +62,24 @@ where
6262

6363
impl<T, E, K: Eq + Hash> Drop for UseQueryCleaner<T, E, K> {
6464
fn drop(&mut self) {
65-
let was_last_listener = {
66-
let mut queries_registry = self.client.queries_registry.write_unchecked();
67-
let query_listeners = queries_registry.get_mut(&self.registry_entry).unwrap();
68-
// Remove this listener
69-
query_listeners.listeners.remove(&self.scope_id);
70-
query_listeners.listeners.is_empty()
65+
let mut queries_registry = match self.client.queries_registry.try_write_unchecked() {
66+
Err(dioxus_lib::prelude::BorrowMutError::Dropped(_)) => {
67+
// It's safe to skip this error as the RadioStation's signals could have been dropped before the caller of this function.
68+
// For instance: If you closed the app, the RadioStation would be dropped along all it's signals, causing the inner components
69+
// to still have dropped signals and thus causing this error if they were to call the signals on a custom destructor.
70+
return;
71+
}
72+
Err(e) => panic!("Unexpected error: {e}"),
73+
Ok(v) => v,
7174
};
7275

76+
let query_listeners = queries_registry.get_mut(&self.registry_entry).unwrap();
77+
// Remove this listener
78+
query_listeners.listeners.remove(&self.scope_id);
79+
7380
// Clear the queries registry of this listener if it was the last one
74-
if was_last_listener {
75-
self.client
76-
.queries_registry
77-
.write_unchecked()
78-
.remove(&self.registry_entry);
81+
if query_listeners.listeners.is_empty() {
82+
queries_registry.remove(&self.registry_entry);
7983
}
8084
}
8185
}
@@ -126,73 +130,61 @@ where
126130
K: 'static + Eq + Hash + Clone,
127131
{
128132
let client = use_query_client();
129-
use_memo_with_old_value(
130-
query_keys.clone(),
131-
|prev_query: Option<UseQuery<T, E, K>>| {
132-
// If there is an previous query it means they query keys have changed.
133-
if let Some(prev_query) = prev_query {
134-
let prev_entry = &prev_query.cleaner.peek().registry_entry;
135-
let mut queries_registry = client.queries_registry.write_unchecked();
136-
// Remove the entry from the previous query
137-
queries_registry.remove(prev_entry).unwrap();
133+
use_sync_memo(query_keys.clone(), || {
134+
let mut query = query();
135+
query.registry_entry.query_keys = query_keys.to_vec();
136+
137+
let registry_entry = query.registry_entry;
138+
let mut queries_registry = client.queries_registry.write_unchecked();
139+
140+
// Create a group of listeners for the given [RegistryEntry] key.
141+
let query_listeners =
142+
queries_registry
143+
.entry(registry_entry.clone())
144+
.or_insert(QueryListeners {
145+
listeners: HashSet::default(),
146+
value: QueryValue::new(RwLock::new(CachedResult::new(
147+
query.initial_value.unwrap_or_default(),
148+
))),
149+
query_fn: query.query_fn,
150+
});
151+
152+
// Register this listener's scope
153+
query_listeners
154+
.listeners
155+
.insert(current_scope_id().unwrap());
156+
157+
let value = query_listeners.value.clone();
158+
159+
// Asynchronously initialize the query value
160+
spawn({
161+
to_owned![registry_entry];
162+
async move {
163+
client.run_new_query(&registry_entry).await;
138164
}
165+
});
139166

140-
let mut query = query();
141-
query.registry_entry.query_keys = query_keys.to_vec();
142-
143-
let registry_entry = query.registry_entry;
144-
let mut queries_registry = client.queries_registry.write_unchecked();
145-
146-
// Create a group of listeners for the given [RegistryEntry] key.
147-
let query_listeners =
148-
queries_registry
149-
.entry(registry_entry.clone())
150-
.or_insert(QueryListeners {
151-
listeners: HashSet::default(),
152-
value: QueryValue::new(RwLock::new(CachedResult::new(
153-
query.initial_value.unwrap_or_default(),
154-
))),
155-
query_fn: query.query_fn,
156-
});
157-
158-
// Register this listener's scope
159-
query_listeners
160-
.listeners
161-
.insert(current_scope_id().unwrap());
162-
163-
let value = query_listeners.value.clone();
164-
165-
// Asynchronously initialize the query value
166-
spawn({
167-
to_owned![registry_entry];
168-
async move {
169-
client.run_new_query(&registry_entry).await;
170-
}
171-
});
172-
173-
UseQuery {
167+
UseQuery {
168+
client,
169+
value,
170+
scope_id: current_scope_id().unwrap(),
171+
cleaner: Signal::new(UseQueryCleaner {
174172
client,
175-
value,
173+
registry_entry,
176174
scope_id: current_scope_id().unwrap(),
177-
cleaner: Signal::new(UseQueryCleaner {
178-
client,
179-
registry_entry,
180-
scope_id: current_scope_id().unwrap(),
181-
}),
182-
}
183-
},
184-
)
175+
}),
176+
}
177+
})
185178
}
186179

187180
/// Alternative to [use_memo]
188181
/// Benefits:
189182
/// - No unnecessary rerenders
190-
/// - Access to the previous value when dependencies change
191183
/// Downsides:
192184
/// - T needs to be Clone (cannot be avoided)
193-
fn use_memo_with_old_value<T: 'static + Clone, D: PartialEq + 'static>(
185+
fn use_sync_memo<T: 'static + Clone, D: PartialEq + 'static>(
194186
deps: D,
195-
init: impl FnOnce(Option<T>) -> T,
187+
init: impl FnOnce() -> T,
196188
) -> T {
197189
struct Memoized<T, D> {
198190
value: T,
@@ -207,10 +199,7 @@ fn use_memo_with_old_value<T: 'static + Clone, D: PartialEq + 'static>(
207199
!= Some(&deps);
208200

209201
let new_value = if deps_have_changed {
210-
let prev_value = memoized_value
211-
.take()
212-
.map(|memoized_value| memoized_value.value);
213-
Some(init(prev_value))
202+
Some(init())
214203
} else {
215204
None
216205
};

0 commit comments

Comments
 (0)