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

如何在Pinput验证器中结合HTTP请求实现输入验证?

解决Pinput异步验证的方案

Pinput的validator是同步回调,没法直接嵌入异步HTTP请求逻辑,得换个思路实现异步验证:

方案:在提交时做异步验证,通过状态更新错误提示

把组件改成StatefulWidget维护错误状态,在onSubmit里执行异步校验,再通过errorText展示结果,具体代码如下:

class PinInputScreen extends StatefulWidget {
  const PinInputScreen({super.key});

  @override
  State<PinInputScreen> createState() => _PinInputScreenState();
}

class _PinInputScreenState extends State<PinInputScreen> {
  final GlobalKey<FormFieldState<String>> _pinPutKey = GlobalKey<FormFieldState<String>>();
  String? _errorText;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Pin Input'),
      ),
      body: Center(
        child: PinPut(
          fieldsCount: 6,
          onSubmit: (String pin) async {
            // 执行异步验证
            final error = await myFutureMethod(pin);
            if (error == null) {
              // 验证通过,执行后续逻辑
              _showSnackBar(pin);
              setState(() => _errorText = null);
            } else {
              // 验证失败,更新错误状态并触发校验提示
              setState(() => _errorText = error);
              _pinPutKey.currentState?.validate();
            }
          },
          focusNode: FocusNode(),
          controller: TextEditingController(),
          // 绑定错误文本
          errorText: _errorText,
          validator: (value) {
            // 先做同步基础校验
            if (value?.length != 6) {
              return '请输入6位PIN码';
            }
            // 返回异步验证的错误结果
            return _errorText;
          },
          submittedFieldDecoration: BoxDecoration(
            color: Colors.white,
            borderRadius: BorderRadius.circular(5.0),
            boxShadow: const [
              BoxShadow(
                color: Colors.black26,
                blurRadius: 2.0,
                offset: Offset(0.0, 0.0),
              )
            ],
          ),
        ),
      ),
    );
  }

  void _showSnackBar(String pin) {
    ScaffoldMessenger.of(context).showSnackBar(SnackBar(
      content: Text('PIN : $pin'),
      duration: const Duration(seconds: 2),
    ));
  }

  Future<String?> myFutureMethod(String pin) async {
    // 传入用户实际输入的pin,替换固定值
    final jsonPinValidation = jsonEncode({"phone": "111111", "verificationCode": pin});
    final response = await http.post(
        Uri.parse("https://mydomain.dev/validation"),
        body: jsonPinValidation,
        headers: {'Content-Type': 'application/json'});
    if (response.statusCode == 200) {
      return null;
    } else {
      return "验证码错误";
    }
  }
}

核心逻辑说明

  1. 状态维护:用_errorText存储异步验证的错误信息,通过setState更新UI
  2. 同步校验优先:validator先做长度检查这类同步逻辑,再返回异步验证的结果
  3. 异步验证时机:在用户提交PIN码的onSubmit回调里执行HTTP请求,避免频繁请求
  4. 错误提示触发:验证失败后调用_pinPutKey.currentState?.validate(),让Pinput显示错误文本

内容的提问来源于stack exchange,提问作者Igor Otávio

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.27 16:07:40