React中ModalEditNgonNgu组件点击无法匹配对应item数据问题求助
问题根源及解决方案
你遇到的问题核心有两个:
- 所有模态框共用同一个ID
#myModalEditNgonNgu,Bootstrap通过ID查找模态框时,只会匹配页面中第一个符合的元素,导致无论点击哪个按钮都打开第一个模态框。 - 表单输入框使用
defaultValue赋值,该值仅在组件初始化时生效,后续props.item更新时不会同步,导致模态框始终显示旧数据。
1. 给每个模态框生成唯一ID
在父组件的map循环中,将每个item的唯一标识(推荐用item.id,没有则用index)传给子组件,子组件用这个标识生成唯一的模态框ID。
修改父组件的循环代码:
{langs.map((item, index) => ( <tr key={item.id || index}> // 其他原有代码 <td className='text-primary' style={{maxHeight: '21px',width: '8%',maxWidth: '300px'}} onClick={()=>handleUpdate(item)}> <ModalEditNgonNgu item={item} modalId={`myModalEditNgonNgu-${item.id || index}`}/> </td> </tr> ))}
2. 修改子组件,同步数据并使用唯一ID
- 接收
modalId属性,替换按钮的data-bs-target和模态框的id - 用
useEffect监听props.item变化,同步更新组件内部状态 - 将表单输入框改为受控组件(用
value绑定状态,替代defaultValue)
修改后的子组件关键代码:
const ModalEditNgonNgu = (props) => { const { item, modalId } = props; // 初始化状态时直接用item的值 const [langName, setLangName] = useState(item.language_name); const [titleLang, setTitleLang] = useState(item.title_lang); const [describeLang, setDescribeLang] = useState(item.describe_lang); const [authorLang, setAuthorLang] = useState(item.author_lang); const [rateLang, setRateLang] = useState(item.rate_lang); const [reviewsLang, setReviewsLang] = useState(item.reviews_lang); // 其他状态保持原有初始化逻辑 // 监听item变化,实时同步状态 useEffect(() => { setLangName(item.language_name); setTitleLang(item.title_lang); setDescribeLang(item.describe_lang); setAuthorLang(item.author_lang); setRateLang(item.rate_lang); setReviewsLang(item.reviews_lang); }, [item]); // 原有handleSubmit、resetData等函数保持不变 return ( <> <button type="button" className="btn btn-primary" data-bs-toggle="modal" data-bs-target={`#${modalId}`} style={{ fontSize: '14px' }}> {item.language_name} </button> <div> <div className="modal fade" id={modalId}> <div className="modal-dialog modal-dialog-centered" style={{ minWidth: '700px' }}> <div className="modal-content"> {/* 模态框头部保持不变 */} <div className="modal-body"> <form> <div className="col"> <div className="row-2"> <label htmlFor={`name-lang-${item.id}`} className="form-label fs-6 fw-bolder">Tên ngôn ngữ</label> <input type="text" className="form-control" id={`name-lang-${item.id}`} placeholder="Nhập tên ngôn ngữ...." value={langName} onChange={(e) => setLangName(e.target.value)} /> </div> {/* 其余输入框同理:替换defaultValue为value绑定状态,同时修改id为唯一值 */} <div className="row-2"> <label htmlFor={`title-lang-${item.id}`} className="form-label fs-6 fw-bolder">Tiêu đề</label> <input type="text" className="form-control" id={`title-lang-${item.id}`} placeholder="Nhập tiêu đề...." value={titleLang} onChange={(e) => setTitleLang(e.target.value)} /> </div> {/* 剩下的输入框按此逻辑修改 */} </div> {/* 原有Select组件部分保持不变 */} </form> </div> {/* 模态框底部保持不变 */} </div> </div> </div> </div> </> ); };
额外注意事项
- 表单元素的
id要避免重复,比如将原有的name-campaign改为name-lang-${item.id},防止点击标签时触发错误的输入框。 - 优先使用
item.id作为key和模态框ID的一部分,避免列表更新时因index变化导致的组件异常。
内容的提问来源于stack exchange,提问作者Lê Trung Hiếu
相关产品推荐
相关产品推荐

