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

React多步骤表单如何将选中卡片的分类数据传递到下一步渲染对应内容

实现方案

1. 改造第一步分类选择组件,存储选中分类到全局Context

你已经配置了全局的QuizContext用来跨组件传值,只需要在点击下一步的时候把选中的分类存入Context即可,修改后的TacoCathegories代码如下:

import { Card } from "../../stories/Card";
import { useQuizData } from "../../context/index"
import { useState } from "react";

const tacos = [
  {
    cathegory: 'Meat',
    imgURL: 'https://images.unsplash.com/photo-1560781290-7dc94c0f8f4f?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=3024&q=80'
  },
  {
    cathegory: 'Fish',
    imgURL: 'https://images.unsplash.com/photo-1510130387422-82bed34b37e9?ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&ixlib=rb-1.2.1&auto=format&fit=crop&w=975&q=80'
  },
  {
    cathegory: 'Veggi',
    imgURL: 'https://images.unsplash.com/photo-1572527129705-a6c197003d61?ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&ixlib=rb-1.2.1&auto=format&fit=crop&w=975&q=80'
  },
]

export const TacoCathegories = ({quizStep, prevQuizStep, nextQuizStep}) => {
  // 取消注释,拿到Context的存值方法
  const { setQuizValues } = useQuizData();
  const [isSelected, setisSelected] = useState();

  return (
    <div className={quizStep === 0 ? 'block': 'hidden'}>
      <div className="text-center">
        <h2 className="text-3xl font-extrabold tracking-tight text-gray-600 sm:text-4xl">What is your favourite taco group?</h2>
      </div>
      <div className="max-w-7xl mx-auto py-24 px-4 sm:px-6 lg:px-8">
        <div className="mt space-y-12 lg:space-y-0 lg:grid lg:grid-cols-3 lg:gap-x-8">
          {tacos.map((taco, index) => (
            <Card 
            role="button"
            key={index}
            title={taco.cathegory}
            source={taco.imgURL}
            text={`image of ${taco.cathegory} `}
            selected={isSelected === index}
            onChange={() => setisSelected(index)}
            />
            
          ))}
        </div>
        {tacos[isSelected] && <p>{tacos[isSelected].cathegory}</p>}
        
        <div className="mt-5 sm:mt-8 sm:flex sm:justify-center lg:justify-center">
          <div className="rounded-md shadow">
            <a role="button" tabIndex={0}
              className="w-full flex items-center justify-center px-8 py-3 border border-transparent text-base font-medium rounded-md text-white bg-gray-200 hover:bg-gray-200 focus:outline-none md:py-4 md:text-lg md:px-10 cursor-not-allowed"
            >
              Back
            </a>
          </div>
          <div className="mt-3 sm:mt-0 sm:ml-3">
            <a
              onClick={() => {
                // 先判断是否选中分类
                if (tacos[isSelected]) {
                  // 把选中的分类存入全局Context
                  setQuizValues({
                    selectedCategory: tacos[isSelected].cathegory
                  })
                  // 再跳转到下一步
                  nextQuizStep()
                }
              }}
              // 未选中时禁用下一步按钮,优化体验
              className={`w-full flex items-center justify-center px-8 py-3 border border-transparent text-base font-medium rounded-md text-white md:py-4 md:text-lg md:px-10 ${isSelected !== undefined ? 'bg-yellow-500 hover:bg-yellow-600' : 'bg-gray-200 cursor-not-allowed'}`}
            >
              Next
            </a>
          </div>
        </div>
      </div>
    </div>
  );
}

核心改动点:

  • 取消了useQuizData引入的注释,拿到全局存值方法setQuizValues
  • 修改下一步按钮的点击逻辑,先将选中的分类存入Context再跳转
  • 新增未选中分类时禁用下一步的逻辑,优化交互体验

2. 改造第二步组件,从Context读取分类渲染对应内容

直接在第二步组件中调用useQuizData拿到全局存储的选中分类,根据分类值渲染对应的塔可列表即可,修改后的TacoTypes代码如下:

import { useQuizData } from "../../context/index"
// 可以根据需求配置不同分类对应的塔可列表,这里举个示例
const TACO_TYPE_CONFIG = {
  Meat: [
    { name: '牛肉塔可', img: 'xxx' },
    { name: '猪肉塔可', img: 'xxx' },
    { name: '鸡肉塔可', img: 'xxx' },
  ],
  Fish: [
    { name: '三文鱼塔可', img: 'xxx' },
    { name: '鳕鱼塔可', img: 'xxx' },
    { name: '鲜虾塔可', img: 'xxx' },
  ],
  Veggi: [
    { name: '牛油果塔可', img: 'xxx' },
    { name: '蔬菜塔可', img: 'xxx' },
    { name: '菌菇塔可', img: 'xxx' },
  ]
}

export const TacoTypes = ({quizStep, prevQuizStep, nextQuizStep}) => {
  // 从全局Context拿到选中的分类
  const { data } = useQuizData();
  const selectedCategory = data.selectedCategory;
  // 根据分类拿到对应的塔可列表
  const showTacos = TACO_TYPE_CONFIG[selectedCategory] || [];

    return (
      <div className={quizStep === 1 ? 'block' : 'hidden'}>
        <div>
            <p>你选择的分类是:{selectedCategory}</p>
            <p>对应的塔可类型如下:</p>
            <div className="grid grid-cols-3 gap-4 mt-4">
              {showTacos.map((taco, idx) => (
                <div key={idx} className="border p-2 rounded">
                  {taco.name}
                  {/* 可以替换成Card组件渲染,和第一步逻辑一致 */}
                </div>
              ))}
            </div>
        </div>
        <div className="mt-5 sm:mt-8 sm:flex sm:justify-center lg:justify-center">
          <div className="rounded-md shadow">
            <a role="button" tabIndex={0}
              onClick={prevQuizStep}
              className="w-full flex items-center justify-center px-8 py-3 border border-transparent text-base font-medium rounded-md text-white bg-yellow-500 hover:bg-yellow-600 md:py-4 md:text-lg md:px-10"
            >
              Back
            </a>
          </div>
          <div className="mt-3 sm:mt-0 sm:ml-3">
            <a
              onClick={nextQuizStep}
              className="w-full flex items-center justify-center px-8 py-3 border border-transparent text-base font-medium rounded-md text-white bg-yellow-500 hover:bg-yellow-600 md:py-4 md:text-lg md:px-10"
            >
              Next
            </a>
          </div>
        </div>
      </div>
    )
}

额外小提示:你代码里的yallow是拼写错误,正确应为yellow,可以顺便修正避免样式不生效。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.09 00:48:03