React中如何将数组映射对象的ID传递至后端?
问题描述
我需要将数组映射生成的每个对象的ID传递至后端,每个对象对应一个独立按钮,点击按钮时提交该对象的ID。目前前后端通信正常,但点击提交按钮时ID无法传递至后端;若通过OnChange事件手动输入ID,则可正常传递。请问该如何解决?
代码示例
import React from 'react'; import {format} from "date-fns-tz"; import {Link} from "react-router-dom"; import MailQueueDataService from "../services/mail_queue.service"; class Parent extends React.Component{ constructor(props){ super(props); this.state = { mailqueues_unsent: {}, loading: false } this.parentClassFunction = this.parentClassFunction.bind(this); } parentClassFunction = () => { console.log("TEST"); event.preventDefault(); const url = "/api/v1/mail_queues/authorize_mail_queue"; const { id } = this.state; const body = { id, }; const token = document.querySelector('meta[name="csrf-token"]').content; fetch(url, { method: "POST", headers: { "X-CSRF-Token": token, "Content-Type": "application/json" }, body: JSON.stringify(body) }) .then(response => { if (response.ok) { return response.json(); } throw new Error("Network response was not ok."); }) .then(response => this.props.history.push(window.close())) .catch(error => console.log(error.message)); } render() { return ( <div> <Child parentClassFunction={this.parentClassFunction} /> </div> ) } } class Child extends React.Component{ constructor(props){ super(props); this.state = { mail_queues_unsent: [], loading: false } } onClickSubmitButton = () =>{ this.props.parentClassFunction() }; retrieveMailQueues() { MailQueueDataService.getAll().then(response => { if (this._isMounted) this.setState({ mail_queues_unsent: response.data.mailqueues_unsent, loading: false} ) }).catch(e => { console.log(e) }) } componentDidMount() { this._isMounted = true; this.setState({loading: true}) this.retrieveMailQueues(); } componentWillUnmount() { this._isMounted = false; } render() { if (this.state.loading) { return <div className="col text-center"> Lade Unautorisierte Mails... </div>; } else { const {mail_queues_unsent} = this.state; const allMailsUnsent = mail_queues_unsent.map((mailqueues_unsent, index) => ( <div className="col"> <div key={index}> <h4><b>Empfänger:</b>{mailqueues_unsent.company_name}</h4> <b>Datum Versandfreigabe:</b> {format(new Date(mailqueues_unsent.created_at), 'dd.MM.yyyy hh:mm')} <p><b>Anzahl der Tests:</b> {mailqueues_unsent.trials_count}</p> <b>Tests:</b> <p>{mailqueues_unsent.trials.map(trial => <Link to={"/trials/" + trial.id}> <p>{trial.certificate_number}</p></Link>)}</p> <form onSubmit={this.parentClassFunction}> <label htmlFor="id"></label> <input type="text" name="id" id="id" value={mailqueues_unsent.id} className="form-control" onChange={this.onChange} /> <button onClick={this.onClickSubmitButton.bind(this)}>CLICK</button> </form> </div> </div> )); const noMailQueues = ( <div> <h4> Kein Unautorisierte Mails vorhanden. </h4> </div> ); return ( <div> {mail_queues_unsent.length > 0 ? allMailsUnsent : noMailQueues} </div> ) } } } export default Parent;
解决方案
问题核心在于父组件的parentClassFunction尝试从自身state获取id,但该state中从未存储过对应的值;同时子组件点击按钮时没有将当前项的id传递给父函数。以下是具体修复步骤:
1. 修改父组件的parentClassFunction,使其接收id参数
不再依赖父组件state,直接使用传入的id构造请求体:
parentClassFunction = (id) => { console.log("TEST"); const url = "/api/v1/mail_queues/authorize_mail_queue"; const body = { id }; const token = document.querySelector('meta[name="csrf-token"]').content; fetch(url, { method: "POST", headers: { "X-CSRF-Token": token, "Content-Type": "application/json" }, body: JSON.stringify(body) }) .then(response => { if (response.ok) { return response.json(); } throw new Error("Network response was not ok."); }) .then(() => { // 原代码中history.push和window.close逻辑冲突,根据需求保留其一 window.close(); }) .catch(error => console.log(error.message)); }
2. 子组件修改点击事件,传递当前项的id
根据是否需要保留手动编辑ID的功能,有两种方案:
方案A:移除不必要的input和form(推荐)
如果不需要手动修改ID,直接传递当前项的ID即可:
// Child组件中修改点击事件方法 onClickSubmitButton = (id) => { this.props.parentClassFunction(id); }; // 在render的map循环中替换原form部分 <div> {/* 原有内容保持不变 */} <button onClick={() => this.onClickSubmitButton(mailqueues_unsent.id)}>CLICK</button> </div>
方案B:保留input(允许手动修改ID)
如果需要让用户编辑ID,补充状态管理和输入变更逻辑:
// Child组件constructor中添加状态存储编辑后的ID constructor(props){ super(props); this.state = { mail_queues_unsent: [], loading: false, editedIds: {} // 存储每个项的编辑后ID } } // 添加输入变更处理方法 handleIdChange = (itemId, value) => { this.setState(prevState => ({ editedIds: { ...prevState.editedIds, [itemId]: value } })); }; // 修改点击事件方法 onClickSubmitButton = (originalId) => { // 优先使用编辑后的ID,无编辑则用原ID const submitId = this.state.editedIds[originalId] || originalId; this.props.parentClassFunction(submitId); }; // 在render的map循环中修改form部分 <form onSubmit={(e) => { e.preventDefault(); this.onClickSubmitButton(mailqueues_unsent.id); }}> <label htmlFor={`id-${mailqueues_unsent.id}`}></label> <input type="text" name="id" id={`id-${mailqueues_unsent.id}`} // 唯一ID避免DOM冲突 value={this.state.editedIds[mailqueues_unsent.id] || mailqueues_unsent.id} className="form-control" onChange={(e) => this.handleIdChange(mailqueues_unsent.id, e.target.value)} /> <button type="submit">CLICK</button> </form>
3. 其他优化点
- 循环中的
key改用mailqueues_unsent.id而非index,避免组件复用导致的异常:key={mailqueues_unsent.id} - 移除Child组件中无效的
form绑定(原代码中form的onSubmit指向不存在的this.parentClassFunction)
内容的提问来源于stack exchange,提问作者Dominik L
相关产品推荐
相关产品推荐

