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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 15:00:47