Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Flutter widget state not updating - throws 'Looking up a deactivated widget's ancestor is unsafe'

Tags:

flutter

I am trying to implement login/logout in Flutter using this example. Log in works fine and the console output is:

flutter: LOGIN WIDGET BUILD CONTEXT:
flutter: LoginScreen(dirty, state: LoginScreenState#552db)
flutter: _ctx:
flutter: LoginScreen(state: LoginScreenState#552db)

But after logging out, I can't log back in (the context is lost). After logging out and then trying to log back in, the context within onAuthStateChanged() is lost after logout:

flutter: LOGIN WIDGET BUILD CONTEXT:
flutter: LoginScreen(dirty, state: LoginScreenState#d112e)
flutter: _ctx
flutter: LoginScreen

login.dart

class LoginScreen extends StatefulWidget {
  @override
  State<StatefulWidget> createState() {
    return new LoginScreenState();
  }
}
class LoginScreenState extends State<LoginScreen>

   BuildContext _ctx;

   @override
   onAuthStateChanged(AuthState state) {
      print("_ctx");
      print(_ctx.toString());   
      if(state == AuthState.LOGGED_IN) { 
         print("ready to login");
         Navigator.of(_ctx).pushReplacementNamed("/home");  
      } 
   }

   @override
   Widget build(BuildContext context) {
      _ctx = context;
      print("LOGIN WIDGET BUILD CONTEXT:");
      print(_ctx.toString());
   }
}

home.dart

class Settings extends StatelessWidget {

  @override
  Widget build(BuildContext context) => new Container(
    child: new ListView(
        children: <Widget>[
          new ListTile(
            //leading: Icon(Icons.map),
            title: new Text('About')
          ),
          new ListTile(
            //leading: Icon(Icons.photo_album),
            title: new Text('Logout'),
            onTap: () {
               Navigator.of(context).pushReplacementNamed("/login");
            }
          )
        ],
      ),
    );  

The routes:

final routes = {
  '/login': (BuildContext context) => new LoginScreen(),
  '/home': (BuildContext context) => new Tabs(),
  '/' : (BuildContext context) => new LoginScreen(),
};

Wy isn't _ctx updated in onAuthStateChanged() and is there a better way to handle login state?

like image 580
lilbiscuit Avatar asked Jul 06 '18 14:07

lilbiscuit


1 Answers

You are reusing an old BuildContext instance. Don't save the instance in the build method. You should never ever do this.

Your LoginScreen is a StatefulWidget and it's state (LoginScreenState) already has context property. Try using this instead.

You also need to dispose the listener, the example already has a dispose(AuthListener) method that you can use.

@override
void dispose() {
  super.dispose(); // always call super for dispose/initState
  AuthStateProvider().dispose(this);
}

In general the example is pretty old and I would suggest finding a more recent tutorial. Flutter and Dart is evolving very fast and a 2 year old example is not the way to go.

like image 146
kuhnroyal Avatar answered Sep 28 '22 16:09

kuhnroyal