You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter中Consumer组件未监听AuthenticationDetails状态更新求助

Flutter中Consumer无法监听AuthenticationDetails状态变化问题

在Flutter项目中使用Consumer组件监听AuthenticationDetails的状态变化,需求是登录后保存accessToken,当isAuth为true时跳转至首页。目前已成功获取接口响应并存储数据,但Consumer始终无法监听到状态变化,无法触发页面跳转。

相关代码

main.dart 代码

return MultiProvider(
  providers: [
    ChangeNotifierProvider(
      create: (context) => UserBookings(),
    ),
    ChangeNotifierProvider(
      create: (context) => AuthenticationDetails(),
    ),
    ChangeNotifierProvider(create: (context) => FetchPlaces()),
    ChangeNotifierProvider(
      create: (context) => Authclass(),
    ),
  ],
  child: Consumer<AuthenticationDetails>(
      builder: (context, value, _) => MaterialApp(
            primarySwatch: Colors.red,
            home: value.isAuth ? PrepareRide() : Otp(),
            routes: {
              'verifyotp': (context) =>
                  value.isAuth ? const PrepareRide() : const VerifyOtp(),
              'mapview': (context) => const PrepareRide(),
            },
          ),
  ),
);

AuthenticationDetails 类代码

import 'dart:convert';

import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;

import 'cabapi.dart';

class AuthenticationDetails extends ChangeNotifier {
  int? sessionId;
  String? acessToken;
  DateTime? acessTokenExpiryDate;
  String? refreshToken;
  DateTime? refreshTokenExpiryDate;

  bool get isAuth {
    return token != null;
  }

  String? get token {
    if (acessTokenExpiryDate != null &&
        acessTokenExpiryDate!.isAfter(DateTime.now()) &&
        acessToken != null) {
      return acessToken;
    }
    return null;
  }

  bool get refresh {
    return refreshtoken != null;
  }

  String? get refreshtoken {
    if (refreshTokenExpiryDate != null &&
        refreshTokenExpiryDate!.isAfter(DateTime.now()) &&
        refreshToken != null) {
      return refreshToken; // 原代码错误返回acessToken,修正为refreshToken
    }
    return null;
  }

  Future<void> registerUser(String? phoneNumber, BuildContext context) async {
    final url = Ninecabsapi().urlHost + Ninecabsapi().login;
    try {
      var response = await http.post(Uri.parse(url),
          headers: {'Content-Type': 'application/json; charset=UTF-8'},
          body: json.encode({'mobileno': phoneNumber}));
      var userDetails = json.decode(response.body);

      sessionId = userDetails['data']['session_id'];
      acessToken = userDetails['data']['access_token'];
      acessTokenExpiryDate = DateTime.now().add(
        Duration(seconds: userDetails['data']['access_token_expires_in']),
      );
      refreshToken = userDetails['data']['refresh_token'];
      refreshTokenExpiryDate = DateTime.now().add(
        Duration(seconds: userDetails['data']['refresh_token_expires_in']),
      );
      print(isAuth);
      notifyListeners();
    } catch (e) {
      print(e);
    }
  }
}

问题原因及解决方法

  1. 语法结构错误:原main.dart中,home和routes参数写在了MaterialApp的外部,导致Consumer的builder函数没有将这两个参数包含在重建范围内。状态变化时,home和routes的判断不会更新,自然无法触发页面跳转。修正后将home和routes放入MaterialApp的参数列表中,确保状态变化时整个MaterialApp的相关配置会重新构建。

  2. getter方法错误:refreshtoken getter方法中错误返回了acessToken,应该返回refreshToken。虽然这不是导致Consumer不监听的直接原因,但会影响refresh状态的判断,建议修正。

完成上述修正后,调用registerUser更新状态并调用notifyListeners()时,Consumer就能监听到AuthenticationDetails的变化,根据isAuth的值正确切换首页或触发路由跳转。

内容的提问来源于stack exchange,提问作者Santosh Kumar

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.26 02:39:09