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

如何在点击HostingCard后,在ContactFormular组件展示对应卡片信息?

问题分析与解决方案

你的当前代码不可行,存在几个关键问题:父组件传递的 props 不全、重复渲染表单、表单交互逻辑冲突、状态管理分散。以下是具体的修复和实现方案:

核心问题点

  1. 父组件未传递 post、showContactDialog、setShowContactDialog 等必要 props,直接使用会导致报错
  2. 每个 HostingCard 内部都渲染了 ContactFormular,会生成3个重复表单,无法精准控制显示选中卡片的信息
  3. input 和 label 的 id/for 属性不匹配,点击标签无法选中单选框
  4. 按钮外层 div 和按钮本身的 onClick 嵌套,可能引发事件冒泡导致逻辑混乱

实现步骤

1. 调整父组件:统一状态管理

将表单、选中卡片等状态提升到父组件,只渲染一个 ContactFormular,通过状态控制显示/隐藏及传递选中卡片信息。

import { useState } from 'react';
import HostingCard from './HostingCard';
import ContactFormular from './ContactFormular';

const HostingList = () => {
  // 从WP API获取的套餐数据
  const [hostings, setHostings] = useState([]);
  // 存储选中的套餐信息
  const [selectedHosting, setSelectedHosting] = useState(null);
  // 控制表单显示/隐藏
  const [showContactDialog, setShowContactDialog] = useState(false);
  // 其他全局状态(根据你的业务需求保留)
  const [pro, setPro] = useState(false);
  const [ssl, setSsl] = useState(false);

  // 处理卡片选中逻辑
  const handleSelectHosting = (hosting) => {
    setSelectedHosting(hosting);
    setShowContactDialog(true);
    setPro(false);
  };

  // 表单提交逻辑
  const handleSubmit = (e) => {
    e.preventDefault();
    // 这里可以使用 selectedHosting 处理提交
    console.log('提交的套餐:', selectedHosting);
    setShowContactDialog(false);
  };

  return (
    <div>
      {/* 渲染套餐卡片 */}
      {hostings.map((hosting) => (
        <HostingCard
          key={hosting.id}
          hosting={hosting}
          onSelect={handleSelectHosting}
          pro={pro}
          setPro={setPro}
          {/* 如果需要post数据,确保父组件有该数据并传递 */}
          // post={yourPostData}
        />
      ))}

      {/* 仅渲染一个表单,根据状态显示 */}
      {showContactDialog && selectedHosting && (
        <ContactFormular
          hosting={selectedHosting}
          showContact={showContactDialog}
          setShowContact={setShowContactDialog}
          handleSubmit={handleSubmit}
          ssl={ssl}
          pro={pro}
          setPro={setPro}
          // post={yourPostData}
        />
      )}
    </div>
  );
};

export default HostingList;

2. 重构 HostingCard 组件:简化逻辑

移除不必要的 props,修复交互问题,将选中逻辑委托给父组件。

const HostingCard = ({ hosting, onSelect, pro, setPro /*, post */ }) => {
  // 生成唯一的单选框ID,确保和label匹配
  const radioId = `hosting-${hosting.id}`;

  return (
    <div className='noselect hosting-options'>
      <input type="radio" id={radioId} name="startup" />
      <div className='card selected-card'>
        <form>
          {/* 修复label的for属性与input的id匹配 */}
          <label htmlFor={radioId} className='label'>
            <div className='card-header'>
              <h5>{hosting.acf.title}</h5>
              <p>{hosting.acf.beskrivelse}</p>
            </div>
            <div className='pakke-detaljer'>
              <div>
                <p style={{ display: hosting.acf.deltaljer ? 'block' : 'none' }}>
                  {hosting.acf.deltaljer}
                </p>
              </div>
            </div>
            <div className='button-header'>
              {/* 设为button类型,避免触发表单默认提交 */}
              <button
                type="button"
                className='btn'
                onClick={() => {
                  setPro(false);
                  onSelect(hosting);
                }}
              >
                Vælg
              </button>
            </div>
          </label>
        </form>
      </div>
    </div>
  );
};

export default HostingCard;

3. ContactFormular 组件接收选中数据

在 ContactFormular 中直接使用 props.hosting 即可获取当前选中卡片的信息,比如:

const ContactFormular = ({ hosting, ...restProps }) => {
  return (
    <div className="contact-form">
      <h3>请联系我们 - {hosting.acf.title}</h3>
      <p>套餐描述:{hosting.acf.beskrivelse}</p>
      {/* 其他表单内容 */}
    </div>
  );
};

export default ContactFormular;

关键优化点

  • 状态提升:将选中卡片、表单显示状态统一放在父组件管理,符合React单向数据流原则
  • 避免重复渲染:只渲染一个表单,通过状态控制显示,提升性能
  • 修复交互问题:确保单选框和标签的ID匹配,按钮类型设为button避免默认提交
  • 简化组件职责:HostingCard 只负责展示卡片和触发选中事件,表单逻辑交给父组件和 ContactFormular 处理

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.16 00:20:53