flutter 未处理的异常:在_ScreenState.initState()完成之前调用了inheritFromWidgetOfExactType(_LocalizationsScope)或inheritFromElement()

4zcjmb1e  于 2023-03-31  发布在  Flutter
关注(0)|答案(6)|浏览(190)

我正在调用initial方法来使用initState从API加载数据。但它导致了一个错误。这里是错误:

Unhandled Exception: inheritFromWidgetOfExactType(_LocalizationsScope) or inheritFromElement() was called before _ScreenState.initState() completed.
When an inherited widget changes, for example if the value of Theme.of() changes, its dependent widgets are rebuilt. If the dependent widget's reference to the inherited widget is in a constructor or an initState() method, then the rebuilt dependent widget will not reflect the changes in the inherited widget.

我的代码是:

@override
  void initState() {
    super.initState();

    this._getCategories();
  }

  void _getCategories() async {
    AppRoutes.showLoader(context);
    Map<String, dynamic> data = await apiPostCall(
      apiName: API.addUser,
      context: context,
      parameterData: null,
      showAlert: false,
    );
    if(data.isNotEmpty){
      AppRoutes.dismissLoader(context);
      print(data);

    }else {
      AppRoutes.dismissLoader(context);
    }
   }
4xy9mtcn

4xy9mtcn1#

您需要在initState完成后调用_getCategories

@override
void initState() {
   super.initState();

   Future.delayed(Duration.zero, () {
      this._getCategories();
   });

   // Could do this in one line: Future.delayed(Duration.zero, this._getCategories);
}

此外,您可以使用addPostFrameCallback以不同的方式完成此任务。为了使此任务更容易,您可以创建一个mixin以添加到StatefulWidgets。

mixin PostFrameMixin<T extends StatefulWidget> on State<T> {
  void postFrame(void Function() callback) =>
      WidgetsBinding.instance?.addPostFrameCallback(
        (_) {
          // Execute callback if page is mounted
          if (mounted) callback();
        },
      );
}

然后,你只需要将这个mixin插入到你的页面,就像这样:

class _MyPageState extends State<MyPage> with PostFrameMixin {
  @override
  void initState() {
    super.initState();

    postFrame(_getCategories);
  }
}
hsvhsicv

hsvhsicv2#

使用didChangeDependencies方法,该方法在initState之后调用。
对于您的示例:

@override
void initState() {
  super.initState();
}

@override
void didChangeDependencies() {
  super.didChangeDependencies();

  this._getCategories();
}

void _getCategories() async {
  // Omitted for brevity
  // ...

 }
mrfwxfqh

mrfwxfqh3#

Adding a frame callback可能比使用零持续时间的Future.delayed更好-它更明确和清晰地说明发生了什么,而这种情况正是帧回调的设计目的:

@override
  void initState() {
    super.initState();

    WidgetsBinding.instance.addPostFrameCallback((_) async {
      _getCategories();
    });
  }
k7fdbhmy

k7fdbhmy4#

一种替代方案是将其放置在PostFrameCallback内部,其在initStateBuild之间。

@override
void initState() {
super.initState();
WidgetsBinding.instance.addPostFrameCallback((_) => getData());
}
    
Future<void> getData() async {
// perform fetch logic
}
9fkzdhlc

9fkzdhlc5#

有很多方法可以解决这个问题,重写initState方法:

@override
void initState() {
  super.initState();
  // Use any of the below code here. 
}
  • 使用SchedulerBinding mixin:
SchedulerBinding.instance!.addPostFrameCallback((_) {
  // Call your function
});
  • 使用Future类:
Future(() {
  // Call your function
});
  • 使用Timer类:
Timer(() {
  // Call your function
});
hts6caw3

hts6caw36#

我认为最好的解决方案是使用Widget构建的上下文。并在构建后将method _getCategories(context)粘贴到树的上下文中。因此,Widget树没有问题。

相关问题