DioxusLabs / dioxus

Fullstack app framework for web, desktop, mobile, and more.
https://dioxuslabs.com
Apache License 2.0
20.32k stars 779 forks source link

State in components that are removed are never dropped #769

Closed ealmloff closed 1 year ago

ealmloff commented 1 year ago

Problem

The state create in use_state hooks in components that are created and then removed are never have there drop handler called.

Steps To Reproduce

Run:

use dioxus::prelude::*;

fn main() {
    dioxus_desktop::launch(app);
}

fn app(cx: Scope) -> Element {
    let count = if cx.generation() % 2 == 0 { 10 } else { 0 };
    if cx.generation() < 10 {
        cx.needs_update();
    }

    render! {
        (0..count).map(|_| rsx!{
            Comp {}
        })
    }
}

fn Comp(cx: Scope) -> Element {
    cx.use_hook(|| Drops);
    render! {
        div{}
    }
}

struct Drops;

impl Drop for Drops {
    fn drop(&mut self) {
        println!("Dropped!");
    }
}

Expected behavior

The message Dropped should be called when the program starts, not just when it is closed and the VirtualDom is dropped

Environment:

Questionnaire

ealmloff commented 1 year ago

It looks like drop_scope is never called in remove_component here: https://github.com/DioxusLabs/dioxus/blob/master/packages/core/src/diff.rs#L918

jkelleyrtp commented 1 year ago

Good catch, yep, the "remove component node" function should just be returning the props from the scope to the vcomponent in case the vcomponent gets rendered again.

jkelleyrtp commented 1 year ago

Put up #771

ealmloff commented 1 year ago

fixed in #771