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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 16:45:31