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

ReactJS动态多输入字段带搜索提示点击无法更新输入值问题

问题修复方案

存在的问题

  • 基础拼写错误:子组件遍历提示项时将参数port错写为val,父组件渲染判断条件将forms.length错写为form.length
  • 状态设计不合理:所有动态生成的表单共用同一套输入值、搜索结果状态,导致修改任意表单会同步影响所有表单;直接将React组件实例存入状态属于反模式,应该存储每个表单的独立状态数据
  • 缺少选中结果的数组存储逻辑,没有对应状态维护所有选中的搜索项

修复后代码

子组件代码

import React from "react";
import { Col, Form } from "react-bootstrap";
const FormComponent = (props) => {
  return (
    <Col xs={12} sm={12} md={12} lg={4}>
      <Form.Group className="mb-3">
        <Form.Label>DEPARTURE</Form.Label>
        <Form.Control
          type="text"
          value={props.value}
          onChange={(e) => props.onChange(props.formId, e.target.value)}
        />
      </Form.Group>
      {props.arr &&
        props.arr.map((port, i) => (
          <div key={i} onClick={() => props.onSelect(props.formId, port.name)}>
            {port.name}
          </div>
        ))}
    </Col>
  );
};
export default FormComponent;

父组件代码

import React, { useState } from "react";
import { Container, Button } from "react-bootstrap";
import axios from "axios";
import FormComponent from "./FormComponent"; // 可根据实际路径调整

const ParentComponent = () => {
  // 存储所有表单的独立状态,每个项包含id、输入值、搜索结果
  const [forms, setForms] = useState([]);
  // 存储所有选中的结果,为字符串数组
  const [selectedValues, setSelectedValues] = useState([]);

  // 新增表单
  const newForm = () => {
    setForms(prev => [...prev, {
      id: Date.now(),
      value: '',
      result: []
    }]);
  };

  // 处理表单输入变化,触发搜索
  const handleFormChange = async (formId, newValue) => {
    // 更新当前表单的输入值
    const updatedForms = forms.map(form => {
      if (form.id === formId) {
        return { ...form, value: newValue };
      }
      return form;
    });
    setForms(updatedForms);

    // 输入为空时清空结果,否则发起搜索请求
    if (!newValue.trim()) {
      setForms(prev => prev.map(form => form.id === formId ? {...form, result: []} : form));
      return;
    }
    const res = await axios.post(`/api/search/${newValue}`);
    setForms(prev => prev.map(form => form.id === formId ? {...form, result: res.data} : form));
  };

  // 处理选中提示项
  const handleSelect = (formId, selectedVal) => {
    // 更新当前表单的输入值,清空搜索结果
    setForms(prev => prev.map(form => {
      if (form.id === formId) {
        return { ...form, value: selectedVal, result: [] };
      }
      return form;
    }));
    // 将选中值加入结果数组,如需去重可替换为下方注释代码
    setSelectedValues(prev => [...prev, selectedVal]);
    // setSelectedValues(prev => Array.from(new Set([...prev, selectedVal])));
  };

  return (
    <Container>
      <Button
        className="col-lg-5 col-sm-12 mb-2"
        variant="outline-secondary"
        size="lg"
        onClick={newForm}
      >
        Add New Search
      </Button>
      {forms.length > 0
        ? forms.map((form) => (
            <FormComponent
              key={form.id}
              formId={form.id}
              value={form.value}
              onChange={handleFormChange}
              arr={form.result}
              onSelect={handleSelect}
            />
          ))
        : null}
      {/* 可取消下方注释查看选中的字符串数组 */}
      {/* <div>{JSON.stringify(selectedValues)}</div> */}
    </Container>
  );
};

export default ParentComponent;

功能说明

  • 每个动态生成的搜索表单相互独立,输入内容、搜索结果互不干扰
  • 点击提示项后会自动填充当前表单的输入框,同时清空当前表单的搜索提示
  • 所有选中的提示项会自动存入selectedValues字符串数组,可直接在业务逻辑中使用

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.04 13:39:00