我有一个名为AuthenticatingScreen
的有状态小部件,我尝试在其中执行以下流程...
1.输出消息,让用户知道我们正在登录他们
1.获取用户oAuth令牌(调用服务文件)
1.更新消息以让用户知道我们正在加载他们的详细信息
1.获取用户详细信息并将其重定向离开
问题是,在第三步中,我正在重建状态,这反过来又导致build
方法再次被触发,并再次调用服务,从而触发异常。
import 'package:flutter/material.dart';
import 'package:testing/services/auth_service.dart';
class AuthenticatingScreen extends StatefulWidget {
final String token;
AuthenticatingScreen(this.token);
@override
State<AuthenticatingScreen> createState() => _AuthenticatingScreenState();
}
class _AuthenticatingScreenState extends State<AuthenticatingScreen> {
// step 1) our default message
String _message = 'Please wait while we log you in...';
Future<void> _fetchUserDetails() {
return Future.delayed(const Duration(seconds: 3), () {
// ToDo: fetch user details from the server
});
}
@override
Widget build(BuildContext context) {
// step 2) get our oAuth token
AuthService.handleCallback(widget.token).then((accessCode) async {
// step 3) update our message
setState(() => _message = 'We\'re just getting your details');
// step 4) retrieve our user details and redirect away
_fetchUserDetails().then((_) {
Navigator.of(context).pushNamedAndRemoveUntil(
'/home',
(Route<dynamic> route) => false,
);
});
});
/// output our authenticating screen.
return Scaffold(
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
const Padding(
padding: EdgeInsets.only(bottom: 20.0),
child: CircularProgressIndicator(),
),
Text(_message),
],
),
),
);
}
}
**我的问题是:**如何解决这个问题/提取这个逻辑,使其只在创建小部件时才触发,同时仍然可以访问构建上下文以进行导航?
我尝试过使小部件本身无状态化,并将消息和微调器提取到一个单独的小部件中,但仅更改输入参数仍然不能强制进行重建。
2条答案
按热度按时间csbfibhn1#
你可以这样做,我通常使用getx & controller来实现这一点。
1.最好在控制器中分离UI类和服务类
1.使UI类具有状态
1.在onInit()方法中调用API,因为它只调用一次,它将触发服务类
1.在API方法中,当您获得结果200时,启动UI转换
mbzjlibv2#
好的,我已经想出了解决方案。看起来在
build()
方法中进行服务调用是个坏主意。将我的服务调用移到一个void函数中,然后可以在
initState()
方法中调用该函数,这似乎是一种可行的方法。这样,当再次调用
build()
方法进行重建时,只需重新绘制很少的细节。