web-dev-qa-db-ja.com

ステートフルウィジェットを完全に破棄する方法は?

ステートフルウィジェットページを呼び出して、サーバーから情報を取得します。情報が見つからない場合は、情報がないことをユーザーに警告します。ドロワーバックボタンから、前のページに戻ります。繰り返しを非常に速く繰り返し続けると、IntelliJのコンソールメッセージにエラーが表示されますIDE as;

_E/flutter (22681): [ERROR:flutter/Shell/common/Shell.cc(181)] Dart Error: Unhandled exception:
E/flutter (22681): setState() called after dispose(): _BillsPayWaterState#66be5(lifecycle state: defunct, not mounted)
E/flutter (22681): 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. The preferred solution is to cancel the timer or stop listening to the animation in the dispose of the () 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 (22681): 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 of ().
E/flutter (22681): #0      State.setState.<anonymous closure> 
_

私のステートフルウィジェットには@override void initState()があり、@override void dispose()もあります

私の質問は、ドロワーの戻るボタンを使用するときです。ステートフルウィジェットを完全に破棄するにはどうすればよいですか?

これはウィジェットの呼び出しです

_onTap: () {
Navigator.Push(
  context,
  SlideRightRoute(widget: new BillsWaterPay(“S02")),
);
}
_

そしてこれはBillsWaterPayウィジェット

_List<List<dynamic>> _userAskBills;

// TODO: KURUM KODU - SABIT TELEFON
String _kurumKodu = "";
String _noDataText = "";

class BillsWaterPay extends StatefulWidget {
  final String title;

  BillsWaterPay(this.title);

  @override
  _BillsWaterPayState createState() =>
      _BillsWaterPayState();
}

class _BillsWaterPayState extends State<BillsWaterPay> {

  @override
  void initState() {
    // TODO: implement initState
    super.initState();
    _kurumKodu = widget.title;
    _userAskBills;
    _noDataText;
    _loadEverything();
}

Future _loadEverything() async {
    await _getDataFromServer();
}

Future _getDataFromServer() async() {
    …
    …
    if no data
        setState
            _noDataText = “No Data”;  // In here I get an error setState called after dispose

}


@override
void dispose() {
  super.dispose();
      _kurumKodu = widget.title;
    _userAskBills;
    _noDataText;
}
_
8
Nick

問題は、ウィジェットが破棄された後にサーバーからの応答が到着したことが原因であると思います。

setStateを呼び出す前に、ウィジェットがマウントされているかどうかを確認してください。これにより、表示されているエラーを防ぐことができます。

if no data
  if(mounted) {
    setState
        _noDataText = “No Data”;
  }
13