【问题标题】:Flutter setState() or markNeedsBuild() called during build在构建期间调用 Flutter setState() 或 markNeedsBuild()
【发布时间】:2021-08-24 04:49:09
【问题描述】:

我的应用默认打开welcome 屏幕,在该屏幕中我放置了代码来检查用户是否已登录。如果记录重定向到主页,否则会留在欢迎屏幕,但现在返回此错误:

setState() or markNeedsBuild() called during build.

welcome.dart

  late Box userBox;

  @override
  void initState() {
    super.initState();
    userBox = Hive.box<Usermodel>('user'); // get user box

    // see if user data exist in storage or not?
    if(userBox.values.isNotEmpty && userBox.get(0).name.toString().isNotEmpty) {
      Navigator.pushReplacementNamed(context, '/home'); // if exist redirect to home screen
    }
  }

知道如何解决这个错误吗?

更新

如果我的用户已经登录 Vinoth Vino 答案工作正常,但如果我的用户没有登录它会抛出这个错误:

Null check operator used on a null value

来自userBox.get(0)!.name

如果我在get(0) 之后删除!,那么它会说

The getter 'name' was called on null.
Receiver: null
Tried calling: name

更新 2

显然我的用户数据没有存储在我的盒子中(这很奇怪,因为它确实存储在第一次)所以它返回null,但有两个问题涉及到null

  1. 我确实在成功登录后保存了我的用户数据,所以它应该在那里。
//store data in storage in login screen 
var userData = Usermodel()
..name = user.name
..email = user.email
..createdAt = user.createdAt
..approved = user.approved;
final box = Hive.box<Usermodel>('user');
await box.add(userData);
  1. 即使说它没有将用户数据存储在框中,那我为什么要重定向到主屏幕? (我正在检查无效性对吗?userBox.values.isNotEmpty &amp;&amp; userBox.get(0).name.toString().isNotEmpty 它不应该重定向)

【问题讨论】:

  • 也许你的Hive.box&lt;Usermodel&gt;('user') 为空。试试这个userBox.get(0)?.name ?? 'Not Found'
  • 你能检查userBox 是否为空吗?如果不是,那么检查userBox的name是否为空?
  • @VinothVino 显然它是空的,但有两个问题涉及这个空1我确实在成功登录后保存了我的用户数据,所以它应该在那里2 甚至可以说它没有将用户数据存储在框中,那我为什么要重定向到主屏幕?
  • 是的,如果 hive 返回 null,您需要将其导航到登录屏幕。最好将 userBox 创建为可为空的属性,然后检查它是否为空。如果为 null,则打开登录屏幕或主屏幕
  • 我已经更新了我的问题

标签: flutter flutter-hive


【解决方案1】:

addPostFrameCallback()里面添加条件,这个回调会在构建方法完成后触发。

Box? userBox;

@override
void initState() {
  super.initState();
  userBox = Hive.box<Usermodel>('user'); // get user box

  if (userBox != null) {
    WidgetsBinding.instance.addPostFrameCallback((_) {
      if(userBox.values.isNotEmpty && userBox.get(0).name.toString().isNotEmpty) {
        Navigator.pushReplacementNamed(context, '/home'); // if exist redirect to home screen
      }
    });

    or

    SchedulerBinding.instance.addPostFrameCallback((_) {
      if(userBox.values.isNotEmpty && userBox.get(0).name.toString().isNotEmpty) {
        Navigator.pushReplacementNamed(context, '/home'); // if exist redirect to home screen
      }
    });
  } else {
    // Navigate to login screen
  }
}

更新

是的,如果 hive 返回 null,您需要将其导航到登录屏幕。最好将userBox 创建为nullable property,然后检查它是否为空。如果为 null,则打开登录屏幕或主屏幕

【讨论】:

  • 嗨,错误又回来了:/ 这次说Null check operator used on a null value 这是逻辑:1 如果我的用户已登录,您的代码可以正常工作2 如果我的用户仍然没有' t登录它会抛出这个错误。 code:userBox.get(0)!.name
  • 你能用stacktrace更新你的问题吗?也许你用Hive.box&lt;Usermodel&gt;('user') 为空
  • 如何让userBox为空?
  • 检查这个flutter.dev/docs/null-safetydart.dev/null-safety 是否为空安全
  • 找到解决方案 :D 而不是硬编码 0 在 get 我现在使用 userBox!.keys.last 所以它总是返回最新行的键 ${userBox.get(userBox.keys.last).name}
猜你喜欢
  • 2020-12-12
  • 2020-12-28
  • 2021-01-06
  • 2021-05-31
  • 2020-08-11
  • 2020-04-10
  • 2021-04-19
相关资源
最近更新 更多