使用 setState() 时出现 setState() 回调参数返回了一个 Future

Posted

技术标签:

【中文标题】使用 setState() 时出现 setState() 回调参数返回了一个 Future【英文标题】:when using setState () appears setState () callback argument returned a Future 【发布时间】:2019-11-18 16:28:36 【问题描述】:

当我使用 setState() 时,文本出现在调试控制台中..

setState() 回调参数返回一个 Future。 _LoginActivityState#9cd91 上的 setState() 方法是使用返回 Future 的闭包或方法调用的。也许它被标记为“异步”。 不要在 setState() 调用中执行异步工作,而是先执行工作(不更新小部件状态),然后在 setState() 调用中同步更新状态。

   Future<void> login() async 
final formState = formKey.currentState;
if (formState.validate()) 
  formState.save();
  try 
    final response = await UserController.login(
      "username": username,
      "password": password,
    );

    if (response != null && response["success"]) 
      setState(() async 
        accessToken = response['token'];
        //print(token);
        if (accessToken != null) 
          await Http.setAccessToken("Bearer $accessToken");
        
        print('$accessToken');
        final getMe = await AiframeworkController.getProfile();
        print('data: $getMe');
        if (getMe != null && getMe['is_verified'] == true) 
           return Navigator.pushReplacement(
                context, MaterialPageRoute(builder: (context) => MainActivity()));
         else 
          return Center(
                child: CircularProgressIndicator(),
              );
        
      );
    
   catch (e) 
    print(e.message);
  

【问题讨论】:

您可能应该在 setState 方法之外执行异步代码,并且仅在该代码完成时设置状态 【参考方案1】:

setState() 应该只用于设置有状态小部件的新状态。您不应在其中执行 async 操作,也不应从中返回任何内容。我假设 'accessToken' 是您要更改其状态的字段,因此最好在 setState() 之外执行所有其他操作,并将 'accessToken = response['token'];' 留在里面。

【讨论】:

我遇到的唯一例外是可重复使用的 FutureBuilder。您可能希望 Future 实际上是状态,例如,带有刷新按钮的列表,当按下直到加载时显示微调器 @TheTrav 我将如何更新 Futurebuilder 中使用的 Future 状态变量? (因为这个:setState(() =&gt; _futureForFutureBuilder = myFuture); 正好抛出这个错误.. @Jimmy 我从来没有得到令人满意的解决方案。 gist.github.com/thetrav/bca10c1fd1dd123fe5dbbd7c361aabff 是我用来处理不同异步用例的组件集合。在未来构建器的情况下,我尝试将未来作为道具提供,以便在重新运行异步函数时重新构建小部件 @jimmy 我应该否认我的解决方案似乎仍然将未来设置为构建功能的一部分,根据颤振文档,这是一个禁忌,但是我没有遇到任何问题用它。 github.com/flutter/flutter/issues/16218#event-3407922515 有一些进一步的讨论,但大部分都在我头上

以上是关于使用 setState() 时出现 setState() 回调参数返回了一个 Future的主要内容,如果未能解决你的问题,请参考以下文章

(在构建时出现错误)在构建期间调用 setState() 或 markNeedsBuild()。相关的导致错误的小部件是 MaterialApp

我的 setstate 方法被多次调用,这导致在 React Native 中删除项目时出现问题

React setState 未能捕获被拒绝的 Promise

尝试在 React 中更改状态时出现未定义的错误

React中的setState使用细节和原理解析

setState():不要直接改变状态。使用 setState()