Flutter登录POST请求中phone_number字段无法更新问题求助
Flutter登录请求中phone_number字段无法更新的问题
开发的登录功能中,输入有效手机号时POST请求返回200,功能正常,但复现错误提示后,请求体里的phone_number字段会永久保留首次输入的值,无法更新。第二次输入新手机号时,请求体仍显示旧值,只有热重载后才会更新。
相关代码
global_variables.dart中的全局请求体
final Map<String, dynamic> loginBody = { "type": "device", "app_id": '1', "email": "example@example.pt", "country_id": '1', "phone_number": phone.text, // 希望重置此处的值 "password": "secret" };
login.dart关键实现代码
@override void initState() { super.initState(); success = false; focusNode.addListener(() { if (!focusNode.hasFocus) { log(phone.text); } }); refreshValues(); } @override void dispose() { focusNode.dispose(); phone.dispose(); super.dispose(); } @override Widget build(BuildContext context) { return !success ? Column( mainAxisAlignment: MainAxisAlignment.center, children: <Widget>[ Padding( padding: const EdgeInsets.all(8.0), child: TextFormField( maxLength: 9, controller: phone, focusNode: focusNode, ), ), ElevatedButton( onPressed: () async { await login(); if (success) { ScaffoldMessenger.of(context).showSnackBar( SnackBar( backgroundColor: Colors.green, content: Text( loginSuccessful.toString(), ), ), ); // ignore: use_build_context_synchronously Navigator.push( context, MaterialPageRoute( builder: (context) => const BreakdownScreen(), ), ); refreshValues(); } else { ScaffoldMessenger.of(context).showSnackBar( SnackBar( backgroundColor: Colors.red, content: Text( loginUnsuccessful.toString(), ), ), ); refreshValues(); } }, child: const Text('Login'), ) ], ) : Container(); } void refreshValues() { setState( () { loginSuccessful = ""; loginUnsuccessful = ""; phone.text = ""; }, ); } Future<void> login() async { try { if (phone.text.length == 9) { var response = await http.post( Uri.parse("http://LOCAL_API/api/login"), body: loginBody, ); if (response.statusCode == 200) { Map<String, dynamic> loginSuccess = json.decode(response.body); Map<String, dynamic> loginTokenOnSuccess = json.decode(response.body); loginToken = loginTokenOnSuccess['data']; setState( () { loginSuccessful = loginSuccess['message']; success = true; // phone.text = ""; }, ); } else { Map<String, dynamic> loginNoSuccess = json.decode(response.body); setState(() { success = false; loginUnsuccessful = loginNoSuccess['message']; }); } } } on Exception catch (e) { log('ERRO ----- ${e.toString()},'); log( json.encode(loginBody), ); } }
问题原因
这是变量状态问题,不是缓存问题。loginBody是全局的final Map,初始化时会把当时phone.text的值赋值给phone_number字段,之后这个Map里的phone_number不会自动更新——即使修改了phone.text,全局Map里的旧值不会同步变化,除非主动更新它。
解决方案
方案1:每次请求前更新全局Map的phone_number字段
在login()方法发起请求前,手动更新loginBody的对应字段:
Future<void> login() async { try { if (phone.text.length == 9) { // 先更新请求体里的手机号 loginBody['phone_number'] = phone.text; var response = await http.post( Uri.parse("http://LOCAL_API/api/login"), body: loginBody, ); // 后续代码不变 } } on Exception catch (e) { // 异常处理代码不变 } }
方案2:每次请求时动态构建请求体(推荐)
放弃全局请求体,在login()方法内动态创建请求体,避免全局变量引发的状态不一致:
Future<void> login() async { try { if (phone.text.length == 9) { // 动态构建请求体 final loginBody = { "type": "device", "app_id": '1', "email": "example@example.pt", "country_id": '1', "phone_number": phone.text, "password": "secret" }; var response = await http.post( Uri.parse("http://LOCAL_API/api/login"), body: loginBody, ); // 后续代码不变 } } on Exception catch (e) { // 异常处理代码不变 } }
内容的提问来源于stack exchange,提问作者Henrique Guimarães
相关产品推荐
相关产品推荐

