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

寻求Formik集成react-autosuggest的示例教程,遇inputProps传递问题

在Formik中集成react-autosuggest的完整示例

我帮你解决在Formik中使用react-autosuggest的问题,你当前代码的核心问题是没有正确将Formik的表单状态管理和Autosuggest的输入属性绑定。下面是修正后的完整实现,包含详细的关键修改说明:

关键修改点

  • 正确初始化Formik的initialValues,包含需要绑定的表单字段receiverCity
  • 重构inputProps,将Formik的value、onChange、onBlur方法与Autosuggest的输入框关联,确保表单状态由Formik统一管控
  • 完善组件内部state的初始化,确保suggestions有默认空数组值
  • 调整Autosuggest的回调逻辑,保证建议列表能正确根据输入值更新

完整代码实现

import React, { Component } from 'react';
import { Formik, Form, FormGroup, Label, Col, FormFeedback, Button } from 'formik';
import Autosuggest from 'react-autosuggest';
import CardHeader from 'react-bootstrap/CardHeader';
import CardBody from 'react-bootstrap/CardBody';
import CardFooter from 'react-bootstrap/CardFooter';
import Row from 'react-bootstrap/Row';

// 模拟的地址建议数据
const locationSuggestion = [
  { locationName: 'Gambir, Jakarta Pusat, DKI Jakarta', districtCode: '31.71.01', postCode: [11220, 11221, 11222] },
  { locationName: 'Koja, Jakarta Utara, DKI Jakarta', districtCode: '31.72.03', postCode: [11220, 11221, 11222] },
  { locationName: 'Tambora, Jakarta Barat, DKI Jakarta', districtCode: '31.73.04', postCode: [11220, 11221, 11222] },
  { locationName: 'Palmerah, Jakarta Barat, DKI Jakarta', districtCode: '31.73.07', postCode: [11220, 11221, 11222] },
  { locationName: 'Tebet, Jakarta Selatan, DKI Jakarta', districtCode: '31.74.01', postCode: [11220, 11221, 11222] },
  { locationName: 'Matraman, Jakarta Timur, DKI Jakarta', districtCode: '31.75.01', postCode: [11220, 11221, 11222] },
];

// 转义正则特殊字符
function escapeRegexCharacters(str) {
  return str.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
}

// 根据输入值获取建议列表
function getSuggestions(value) {
  const escapedValue = escapeRegexCharacters(value.trim());
  if (escapedValue === '') {
    return [];
  }
  const regex = new RegExp('^' + escapedValue, 'i');
  return locationSuggestion.filter(loc => regex.test(loc.locationName));
}

// 获取选中建议的显示值
function getSuggestionValue(suggestion) {
  return suggestion.locationName;
}

// 渲染单个建议项
function renderSuggestion(suggestion) {
  return <span>{suggestion.locationName}</span>;
}

class SCO extends Component {
  constructor(props) {
    super(props);
    // 初始化组件state,存储建议列表和表单初始值
    this.state = {
      suggestions: [],
      receiverCity: ''
    };
  }

  // 获取建议列表的回调
  onSuggestionsFetchRequested = ({ value }) => {
    this.setState({ suggestions: getSuggestions(value) });
  };

  // 清空建议列表的回调
  onSuggestionsClearRequested = () => {
    this.setState({ suggestions: [] });
  };

  render() {
    return (
      <Formik
        initialValues={this.state}
        enableReinitialize
        // 替换为你实际的验证规则Schema
        validationSchema={SocioSchema}
        onSubmit={(values) => {
          // 处理表单提交逻辑
          console.log('提交的表单值:', values);
        }}
      >
        {(props) => (
          <Form onSubmit={props.handleSubmit}>
            <CardHeader></CardHeader>
            <CardBody>
              <Row>
                <Col xs="12" sm="8">
                  <FormGroup row>
                    <Label htmlFor="receiverCity" className="col-md-3 col-form-label-sm text-right">
                      Kecamatan / Kota
                    </Label>
                    <Col xs="12" md="7">
                      <Autosuggest
                        suggestions={this.state.suggestions}
                        onSuggestionsFetchRequested={this.onSuggestionsFetchRequested}
                        onSuggestionsClearRequested={this.onSuggestionsClearRequested}
                        getSuggestionValue={getSuggestionValue}
                        renderSuggestion={renderSuggestion}
                        // 关键:正确绑定Formik的表单控制属性到inputProps
                        inputProps={{
                          id: 'receiverCity',
                          value: props.values.receiverCity,
                          onChange: (event, { newValue }) => {
                            // 更新Formik的表单字段值
                            props.handleChange('receiverCity')(event);
                          },
                          onBlur: props.handleBlur('receiverCity'),
                          placeholder: '输入地区名称'
                        }}
                      />
                      {/* 显示Formik的验证错误(需配合touched状态判断) */}
                      {props.errors.receiverCity && props.touched.receiverCity && (
                        <FormFeedback className="help-block" type="invalid">
                          {props.errors.receiverCity}
                        </FormFeedback>
                      )}
                    </Col>
                  </FormGroup>
                </Col>
              </Row>
            </CardBody>
            <CardFooter>
              <Button
                size="sm"
                type="reset"
                className="btn-tumblr btn-brand mr-2"
                onClick={() => props.resetForm()}
              >
                <i className="fa fa-dot-circle-o"></i> <span>Reset</span>
              </Button>
              <Button
                type="submit"
                size="sm"
                className="btn-submit btn-brand mr-2"
                disabled={props.isSubmitting}
              >
                <i className="fa fa-paper-plane"></i> <span>Pesen</span>
              </Button>
            </CardFooter>
          </Form>
        )}
      </Formik>
    );
  }
}

export default SCO;

额外说明

  • 确保你已经正确安装了formik、react-autosuggest以及对应的样式(react-autosuggest需要引入它的官方CSS文件)
  • 验证规则SocioSchema需要你自行定义,比如添加对receiverCity字段的必填验证
  • 当用户选中建议项时,Autosuggest会自动更新输入框的值,同时Formik会同步更新表单状态,无需额外处理

内容的提问来源于stack exchange,提问作者cumibulat

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.06 17:42:50