首页 文章

Dart / flutter:来自initState的字符串数据不能通过setState传递

提问于
浏览
1

昨天我制作了一个简单的小部件来获取数据以显示一些基本信息,但我注意到当我弹回列表时,数据通常不存在,我只得到我的错误文本 .

我认为这是由于这些小部件最初是无状态的,所以我试图将它们转换为有状态,以便在加载页面时重新加载数据 .

这是我收集我的小部件数据的方式:

class BasicDogWidget extends StatefulWidget {
  String URL;

  BasicDogWidget(this.URL);

  @override
  createState() => new BasicDogWidgetState(URL);
}

class BasicDogWidgetState extends State<BasicDogWidget> {
  String URL;
  BasicDogWidgetState(this.URL);

  var result;
  var imageLink;
  var dogName;
  var dogType;
  var dogColor;
  var dogGender;
  var dogAge;

  @override
  initState() {
    fetchImageLink(URL).then((result) {
      setState(imageLink = result);
    });

    fetchDogInfo(URL, 'datas-nev').then((result) {
      setState(dogName = result);
    });

    fetchDogInfo(URL, 'datas-tipus').then((result) {
      setState(dogType = result);
    });

    fetchDogInfo(URL, 'datas-szin').then((result) {
      setState(dogColor = result);
    });

    fetchDogInfo(URL, 'datas-nem').then((result) {
      setState(dogGender = result);
    });

    fetchDogInfo(URL, 'datas-kor').then((result) {
      setState(dogAge = result);
    });

    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    if (imageLink == null) {
      return new Container();
    }

    if (dogName == null) {
      return new Container();
    }

    if (dogType == null) {
      return new Container();
    }

    if (dogColor == null) {
      return new Container();
    }

    if (dogGender == null) {
      return new Container();
    }

    if (dogAge == null) {
      return new Container();
    }

    return buildBasicWidget(
        imageLink, dogName, dogType, dogColor, dogGender, dogAge, URL);
  }
}

但是, fetchDogInfo 收集的数据似乎无法在 setState 方法中传递,因为它是一个字符串 .

E/flutter (12296): [ERROR:topaz/lib/tonic/logging/dart_error.cc(16)] Unhandled exception:
E/flutter (12296): type 'String' is not a subtype of type 'VoidCallback' of 'fn' where
E/flutter (12296):   String is from dart:core
E/flutter (12296): 
E/flutter (12296): #0      State.setState (package:flutter/src/widgets/framework.dart:1086)
E/flutter (12296): #1      BasicDogWidgetState.initState.<anonymous closure> (package:osszefogasaszanhuzokert/dog.dart:230)

有什么办法可以绕过这个问题吗?

2 回答

  • 1

    您正在执行异步代码

    fetchImageLink(URL).then((result) {
    

    这意味着 fetchImageLink(URL) 最终将返回一个值,然后 then(...) 被执行,但是这个调用是异步的,这意味着它被添加到事件队列中供以后执行,代码同步继续执行直到 initState 结束然后 build 直到这个同步代码运行完成,然后执行事件队列中的下一个"task",如果已经完成,则可能是 fetchImageLink() 调用的 then(...) 部分 .

    这应该不是问题 .
    您可以检查该值是否可用

    @override
      Widget build(BuildContext context) {
        if(imageLink == null) {
          return new Container(); // dummy widget until there is something real to render
        }
    
        ... // your other build code
    
  • 1

    颤动有FutureBuilder类 . 它提供了一个小部件,可以完成所有繁重工作以支持异步Future对象 . FutureBuilder的优点是可以直接添加到窗口小部件树,并且根据连接的当前状态,可以显示相关的UI以指示进度,结果或错误 .

    例:

    class JokePageState extends State<JokePage> {
      Future<String> response;
    
      initState() {
        super.initState();
        response = http.read(dadJokeApi, headers: httpHeaders);
      }
    
      Widget build(BuildContext context) {
        return new Scaffold(
          body: new Center(
            child: new FutureBuilder<String>(
              future: response,
              builder: (BuildContext context, AsyncSnapshot<String> snapshot) {
                switch (snapshot.connectionState) {
                  case ConnectionState.none:
                    return const Icon(Icons.sync_problem);
                  case ConnectionState.waiting:
                  case ConnectionState.active:
                    return const CircularProgressIndicator();
                  case ConnectionState.done:
                    final decoded = json.decode(snapshot.data);
                    if (decoded['status'] == 200) {
                      return new Text(decoded['joke']);
                    } else {
                      return const Icon(Icons.error);
                    }
                }
              },
            ),
          ),
        );
      }
    }
    

相关问题