What I'm doing
There are two pages: profile and login page.
The profile page is shown first, but when user not already logged in, profile page doesn't show profile and show login button.
Profile code
bool loggedin = false; // If user already logged in return true
class Profile extends StatefulWidget {
const Profile({Key? key}) : super(key: key);
@override
_Profile createState() => _Profile();
}
class _Profile extends State<Profile> {
@override
Widget build(BuildContext context) {
return loggedin
? Column(children: [ //.... some user information
])
: needLogin(context);
}
}
Widget needLogin(BuildContext context) {
return Center(
TextButton(
onPressed: () {
Navigator.of(context).pushNamed("/login");
},
child: const Text(
"Login",
style: TextStyle(fontSize: 20),
)),
);
}
Loggin page
// The code to login is omitted. if login succeeded do loggedin = true; in setState()
var user = FirebaseAuth.instance.currentUser;
if (user != null) {
Navigator.of(context).pop();
setState(() {
loggedin = true;
});
}
// Then back to profile page automatically
Problem
I did loggedin = true;
in setState()
but profile page still shows login button of needLogin()
.
The reason I wrote needLogin()
outside of StatefulWidget
is to reuse it with other StatefulWidget
.
Question
How can I update previous page when call setState()
in the page which generated by Navigator.of(context).pushNamed()
.
CodePudding user response:
Don't
loggedin
outside of the widget.
Use it within:
class _Profile extends State {
Also, you may want to look into some State Management techniques like Provider with Change Notifier for instance. It's quite easy to use and will do exactly what you need.
UI shouldn't contain the business logic and should be rendered based on some sort of controller. This makes code more consistent, readable and testable.
CodePudding user response:
You have to edit the needLogin
method and also pass the success state/bool back through the Navigator:
Profile Code
class Profile extends StatefulWidget {
const Profile({Key? key}) : super(key: key);
@override
_Profile createState() => _Profile();
}
class _Profile extends State<Profile> {
@override
Widget build(BuildContext context) {
return loggedin
? Column(children: [ //.... some user information
])
: needLogin(context, () => setState(() {loggedIn = true}));
}
}
Widget needLogin(BuildContext context, void Function() setStateFunction) {
return Center(
child: TextButton(
onPressed: () async {
await Navigator.of(context)
.pushNamed("/login")
.then((result) {
if (result as bool) {
setStateFunction.call();
}
});
},
child: const Text(
"Login",
style: TextStyle(fontSize: 20),
)),
);
}
Login page
var user = FirebaseAuth.instance.currentUser;
if (user != null) {
Navigator.pop(context, true);
}