dioxus_hooks/
use_effect.rs1use std::{cell::Cell, rc::Rc};
2
3use dioxus_core::prelude::*;
4use futures_util::StreamExt;
5
6use crate::use_callback;
7
8#[doc = include_str!("../docs/side_effects.md")]
9#[doc = include_str!("../docs/rules_of_hooks.md")]
10#[track_caller]
11pub fn use_effect(mut callback: impl FnMut() + 'static) -> Effect {
12 let callback = use_callback(move |_| callback());
13
14 let location = std::panic::Location::caller();
15
16 use_hook(|| {
17 let (rc, mut changed) = ReactiveContext::new_with_origin(location);
19
20 let effect_queued = Rc::new(Cell::new(false));
22
23 let queue_effect_for_next_render = move || {
28 if effect_queued.get() {
29 return;
30 }
31 effect_queued.set(true);
32 let effect_queued = effect_queued.clone();
33 queue_effect(move || {
34 rc.reset_and_run_in(|| callback(()));
35 effect_queued.set(false);
36 });
37 };
38
39 queue_effect_for_next_render();
40 spawn(async move {
41 loop {
42 let _ = changed.next().await;
44
45 queue_effect_for_next_render();
47 }
48 });
49 Effect { rc }
50 })
51}
52
53#[derive(Clone, Copy)]
55pub struct Effect {
56 rc: ReactiveContext,
57}
58
59impl Effect {
60 pub fn mark_dirty(&mut self) {
62 self.rc.mark_dirty();
63 }
64}