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
相关产品推荐
相关产品推荐

