[Solved] Unhandled Exception: setState() called after dispose()

In this post, we are going to show you how to solve the "Unhandled Exception: setState() called after dispose()" error in Flutter. This error occurs when setState() is called when there is no state anymore. See the example below to solve this error:

E/flutter ( 7586): [ERROR:flutter/lib/ui/ui_dart_state.cc(198)] 
Unhandled Exception: setState() called after dispose():
_Track#37715(lifecycle state: defunct, not mounted) E/flutter ( 7586): This error happens if you call setState()
on a State object for a widget that no longer appears in the widget tree
(e.g., whose parent widget no longer includes the widget in its build).
This error can occur when code calls setState() from a timer or an animation callback.

This error occurs when setState() is called after disposing of the state, in other words, the setState() is called at the time when there is no page active. For example, if you have scheduled or have a listener, which can continue to work even after you have gone back to another screen. And inside the action of the listener or schedule, you may have called the setState to refresh the UI which no longer exists. 

If you look into the error message, you can see the solution in the message itself. 

E/flutter ( 7586): The preferred solution is to cancel the timer or stop listening to
the animation in the dispose() callback. Another solution is to check the
"mounted" property of this object before calling setState() to ensure the object is still in the tree. E/flutter ( 7586): This error might indicate a memory leak if setState()
is being called because another object is retaining a reference to this
State object after it has been removed from the tree. To avoid memory leaks,
consider breaking the reference to this object during dispose().

If this error occurs due to the Timer, which runs the code periodically, it may continue to work even if you exit from the page and go back to another page. You have to cancel the timer and dispose of it while exiting like below:

var timer;
timer = Timer.periodic(Duration(seconds: 3), (timer) {
       // your timer code, you may have called setState() here to refresh UI
});

While dispose():

@override
void dispose() {
    timer.cancel(); //cancel the periodic task
    timer; //clear the timer variable
    super.dispose();
}

Here we have a WebSocket listener, that may not close while the page is closed. In your condition, there may be another kind of listener, but the case is the same, try to understand the scenario. 

late IOWebSocketChannel channel;
channel = IOWebSocketChannel.connect(Uri.parse(url));
channel.stream.listen((message) async {
    //you may have called the setState here.
});

Now, while dispose, cancel the listener, there may be different ways, but for this WebSocket channel:

@override
void dispose() {
    channel.sink.close(); //close the connection
    channel.sink;
    channel;
    super.dispose();
}

Ultimately, if all the solutions won't work try the code below while calling setState():

if (this.mounted) {
  setState(() {
    // Your state update code goes here
  });
}

In this way, you can solve "Unhandled Exception: setState() called after dispose()" error in Flutter.

No any Comments on this Article


Please Wait...