Skip to content

Bug: in dev mode the dispose function is applied to incorrect state #34259

@pasha-omni

Description

@pasha-omni

When using a third-party stateful object that needs to be explicitly disposed of, I'm using an effect that returns a dispose function. In dev mode I observe then that React uses the stateful object after it has been disposed, and then disposes of it a second time.

React version: 19.1.1

Steps To Reproduce

  1. Run the code sample below
  2. Observe the console logs
  3. Navigate away to some other page
import React from "react";

export const TestComponent = () => {
  console.log("Start rendering TestComponent");
  const state = React.useMemo(() => {
    return new State();
  }, []);
  React.useEffect(() => {
    return () => state.dispose();
  }, []);
  console.log("TestComponent rendered", state.id);
  return "Test";
};

class State {
  id: number;
  constructor() {
    this.id = Math.floor(Math.random() * 1000000);
    console.log("new State", this.id);
  }
  dispose() {
    console.log("dispose of state", this.id);
  }
}

The current behavior

Currently, the component is created twice in dev mode (as expected), and each copy creates a new State (as expected). One of those copies then gets disposed during unmount (as expected). However, that same object gets used again in a subsequent render even after it was unmounted (not expected). It then gets disposed of again during subsequent navigation (definitely not expected). The original second copy of the State is not disposed (also not expected).

Start rendering TestComponent
new State 666058
new State 109916
TestComponent rendered 666058
Start rendering TestComponent
TestComponent rendered 666058
dispose of state 666058
Start rendering TestComponent
TestComponent rendered 666058
Start rendering TestComponent
TestComponent rendered 666058
(navigate)
dispose of state 666058

The expected behavior

Start rendering TestComponent
new State 666058
new State 109916
TestComponent rendered 666058
Start rendering TestComponent
TestComponent rendered 109916
dispose of state 109916
Start rendering TestComponent
TestComponent rendered 666058
Start rendering TestComponent
TestComponent rendered 666058
(navigate)
dispose of state 666058

Metadata

Metadata

Assignees

No one assigned

    Labels

    Resolution: StaleAutomatically closed due to inactivityStatus: UnconfirmedA potential issue that we haven't yet confirmed as a bug

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions