【问题标题】:"await" in Widget build FLUTTER小部件构建 FLUTTER 中的“等待”
【发布时间】:2022-02-14 02:53:36
【问题描述】:

我在颤振问题上被困了几个小时。如果你能帮助我,那就太好了。

我需要在我的 Widget build(BuildContext context){} 中放入“await”,但不能放入“async”。 怎么办?

当我测试 void _myAsyncMethod()async{} 时:

【问题讨论】:

  • 你不能让build异步,使用initState,在里面创建另一个异步方法。更多关于async。另一种方法是使用FutureBuilder
  • 好的,谢谢您的回答。我只是尝试使用 FutureBuilder,但没有任何效果......
  • 您使用的是哪个 firebase_auth 版本
  • firebase_auth: "^0.10.0"
  • 您需要的是FutureBuilder。请将您的代码添加为纯文本,以便搜索更友好。

标签: flutter async-await build


【解决方案1】:

要解决您的问题,您可以将 async 放在这样的方法主体中

Before=> Widget build(BuildContext context) {

   

After=> Widget build(BuildContext context) async{

虽然这不会解决您的问题,因为颤振会警告您,因为这不是正确的方法。

在 Flutter 的 build 方法中调用 await 并不是一个好习惯,因为

  1. 一般来说,应用程序需要平均每秒运行 60 帧,因此我们会一遍又一遍地调用 Flutter 的 build 方法来重新渲染 ui。
  2. 另一个原因是,在 build 方法中调用 await function() 会阻塞你的 UI。

解决方案

  1. 使用 FutureBuilder
  2. 在 initState 方法中调用 await auth.currentUser()

解决此问题的另一种方法是使用 FutureBuilder

1 的示例代码

FutureBuilder(
      builder: (BuildContext ctx, AsyncSnapshot<userModel> snapshot) {
        if(ConnectionState.done == snapshot.connectionState) {
          return Text(snapshot.data.userId);
        } else {
          return CircularProgressIndicator();
        }
      },
      future: auth.currentUser(),
    );

示例代码 2(有状态小部件)

late UserModel;   
void initState() {
 UserModel user = await auth.currentUser();   
}

这是非常基本的代码,但足以让您开始使用。

注意:我假设上面提到的userModelauth.currentUser()的响应类型,你可以相应地改变它。

【讨论】:

    【解决方案2】:

    您想要做的不是最佳的,但您可以创建一个方法并将您的 await 变量放在那里:

     late final FirebaseUser _user;
      void _myAsyncMethod()async{
        _user = await auth.currentUser;
      }
    
      @override
      Widget build(BuildContext context) {
        _myAsyncMethod();
        return Scaffold(appBar: AppBar(), body: Container());
      }
    

    【讨论】:

      【解决方案3】:
      1. 如果您使用的是 stateful 小部件,您可以在 initstate() 方法中实例化 firebase 身份验证。
      class testFirless extends StatefulWidget {
        var currentuseid = "";
      
        testFirless({Key? key}) : super(key: key);
      
        @override
        _testFirlessState createState() => _testFirlessState();
      }
      class _testFirlessState extends State<testFirless> {
        @override
        Widget build(BuildContext context) {
          return Container();
        }
      
        // ------------------------------------>heree
        @override
        Future<void> initState() async {
          FirebaseAuth auth = FirebaseAuth.instance;
      
          var user = await auth.currentUser;
          if (user == null) {
            widget.currentuseid = user!.uid;
          } else {
            print('User is signed in!');
          }
        }
      }
      
      1. FutureBuilder
      class fbuilder extends StatelessWidget {
        const fbauth({Key? key}) : super(key: key);
      
        @override
        Widget build(BuildContext context) {
          FirebaseAuth auth = FirebaseAuth.instance;
      
      
      // --------------->
          return Container(child: FutureBuilder(
            builder: (BuildContext ctx, AsyncSnapshot<User> snapshot) {
              if (ConnectionState.done == snapshot.connectionState) {
                return Text(snapshot.data.userId.toString());
              } else {
                return CircularProgressIndicator();
              }
            },
            future: auth.currentUser(),
          ));
        }
      }
      
      1. statelessstateful 小部件中
      String currentuseid="";
              class fbauth extends StatelessWidget {
                const fbauth({Key? key}) : super(key: key);
              
                @override
                Widget build(BuildContext context) {
               
             FirebaseAuth auth = FirebaseAuth.instance;
       //   ------------------------>    
                  auth.currentUser().then((user) {
                    if (user == null) {
                      currentuseid = user!.uid;
                    } else {
                      print('User is signed in!');
                    }
                    // other logic after the user retrieval
                  });
              
                  return Container();
                }
      }
      
      Nb: Instead of instantiating firebase auth in every widget .you must instantiate in `void main` method
      

      【讨论】:

      • 非常感谢您提供的代码。这非常有趣,但我仍然有一个小错误:/ --> error: Undefined name 'currentuseid'。
      • 只需在类之外建立currentuseidcurrentuserid。就像我上面提到的第三种方法一样。String currentuseid="";
      猜你喜欢
      • 2020-09-01
      • 2023-01-14
      • 2021-06-11
      • 2021-07-04
      • 2017-10-19
      • 2020-06-09
      • 2020-11-11
      • 2019-02-10
      • 2021-07-09
      相关资源
      最近更新 更多