0

可能这是我的错或愚蠢的错误,但这就是发生在我身上的事情:

authController.dart:

class AuthController {
BehaviorSubject _hometownController = BehaviorSubject();
Observable get hometown => _hometownController.stream;
void updateHometown(String hometown) {
    _hometownController.add(hometown);
    print(_hometownController.value); <- This always prints the expected value: "Hello!"`
}
}

Login_screen.dart:

class Login2 extends StatelessWidget {
  AuthController authController = new AuthController();
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Builder(
        builder: (BuildContext context) =>
          Container(
            padding: EdgeInsets.all(32.0),
            child: Center(
              child:
                  //Hometown:
                  StreamBuilder(
                    stream: authController.hometown,
                    builder: (BuildContext context, AsyncSnapshot snap) {
                      return ListTile(
                        leading: Icon(Icons.map),
                        title: Text("Hometown:"),
                        subtitle: snap.hasData ? Text(snap.data) : Text("Not set"),
                        onTap: () {
                          authController.updateHometown("Hello!");
                        },
                      );
                    }
                  ),
  ))));}}

一切顺利。但是,如果我在 authController.updateHometown 之前添加一个带有 async 和 await 的异步函数:

Login_screen.dart:

                            onTap: () async {
                              var x = await something(); <- This always successfully completes
                              authController.updateHometown("Hello!");
                            },

流永远不会收到新值,并且 StreamBuilder 永远不会重建!

但是如果我使用 statefulWidget 类:

class Login2 extends StatefulWidget {
  @override
  State<StatefulWidget> createState() => Login2State();
}

class Login2State extends State<Login2> {
  AuthController authController;

  @override
  void initState() {
    authController = new AuthController();
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Builder(
        builder: (BuildContext context) =>
          Container(
            padding: EdgeInsets.all(32.0),
            child: Center(
              child:
                  //Hometown:
                  StreamBuilder(
                    stream: authController.hometown,
                    builder: (BuildContext context, AsyncSnapshot snap) {
                      return ListTile(
                        leading: Icon(Icons.map),
                        title: Text("Hometown:"),
                        subtitle: snap.hasData ? Text(snap.data) : Text("Not set"),
                        onTap: () async {
                          var x = await something();
                          authController.updateHometown("Hello!");
                        },
                      );
     }),))));}}

一切都很顺利,即使我从不调用 setState 为什么会发生这种情况?

4

1 回答 1

1

来自Framework.dart

AStatelessWidget根据具有两个条件的数据构建自身:

  1. 可以在构建小部件时同步读取。和 :
  2. 可能会在小部件的生命周期内发生变化。

这就是为什么当您制作Login2as StatelessWidget,然后authController同步更改数据时,它会立即反映,因为它同时满足这两个条件。但是当你async在内部使用一个函数时,onTap()你会破坏第一个函数。

为什么StatefulWidget使用async函数是因为它的build函数只需要数据更改即可setState()隐式触发,而不管此信息是同步还是异步可用。

于 2019-05-30T12:56:32.633 回答