`use_effect` not running when writing to signal asynchronously
pablosichert opened this issue · comments
Pablo Sichert commented
Heyo,
thank you for this great library! I'm having a problem with signals that I reduced to a minimal example.
I want to run a side effect within a use_effect
that is derived from a signal. The signal itself is not used for rendering.
When writing to this signal asynchronously, I can not get it to fire consistently (it works sometimes, but very rarely).
Steps To Reproduce
Cargo.toml
[package]
name = "signal_asynchronous_write_not_rerendering"
version = "0.0.0"
edition = "2021"
[dependencies]
dioxus = { version = "0.5", features = ["fullstack"] }
log = "0.4"
dioxus-logger = "0.4"
wasm-bindgen-futures = "0.4"
web-sys = "0.3"
[features]
default = []
server = ["dioxus/axum"]
web = ["dioxus/web"]
main.rs
Expand to see full file
use dioxus::prelude::*;
use log::LevelFilter;
use wasm_bindgen_futures::JsFuture;
use web_sys::{
js_sys::{Function, Promise},
window,
};
fn main() {
dioxus_logger::init(LevelFilter::Debug).unwrap();
launch(App);
}
pub async fn sleep(delay: i32) {
let mut callback = |resolve: Function, _reject: Function| {
window()
.unwrap()
.set_timeout_with_callback_and_timeout_and_arguments_0(&resolve, delay)
.unwrap();
};
let promise = Promise::new(&mut callback);
JsFuture::from(promise).await.unwrap();
}
/// ...
/// ...
fn use_delayed_double(x: Signal<usize>) -> Signal<usize> {
let mut foo = use_signal(|| x());
use_memo(move || {
let y = x * 2;
spawn(async move {
log::debug!("Sleeping...");
sleep(100).await;
log::debug!("Writing signal");
*foo.write() = y; // <<---- Writing to the signal.
});
});
foo
}
#[allow(non_snake_case)]
fn App() -> Element {
let mut x = use_signal(|| 123);
let double = use_delayed_double(x);
use_effect(move || {
let double = double();
log::debug!("double: {:?}", double); // <<---- Expecting the side effect to be executed.
});
rsx! {
button {
onclick: move |_| x += 1,
"increment"
},
"x: {x}"
// "double: {double}" // <<---- When commenting this line in, logging "double" works as expected.
}
}
Launch app using dx serve
.
output
[DEBUG] signal_asynchronous_write_not_rerendering - double: 123
[DEBUG] signal_asynchronous_write_not_rerendering - Sleeping...
[DEBUG] signal_asynchronous_write_not_rerendering - Writing signal
Expected behavior
output
[DEBUG] signal_asynchronous_write_not_rerendering - double: 123
[DEBUG] signal_asynchronous_write_not_rerendering - Sleeping...
[DEBUG] signal_asynchronous_write_not_rerendering - Writing signal
[DEBUG] signal_asynchronous_write_not_rerendering - double: 246 <<----
Environment:
- Dioxus version:
dioxus 0.5.4
- Rust version:
rustc 1.76.0 (07dca489a 2024-02-04)
- OS info:
macOS 14.2.1
- App platform:
web
Questionnaire
- I'm interested in fixing this myself but don't know where to start
- I would like to fix and I have a solution
- I don't have time to fix this right now, but maybe later
Pablo Sichert commented
This seems to share the underlying issue with #2307.