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

React中点击按钮切换垂直Tab及获取多Tab数据的问题咨询

步进Tab交互实现

你现有代码的核心问题是同时维护了控制Tab激活的value和控制步进的activeStep两个独立状态,没有同步,且按钮事件绑定错误。调整后完整可运行代码如下:

import React, { useState, useRef } from "react";
import { Tabs, Tab, Grid, Button, Typography, Box } from "@mui/material";

// TabPanel基础逻辑(MUI官方标准实现)
function TabPanel(props) {
  const { children, value, index, ...other } = props;
  return (
    <div role="tabpanel" hidden={value !== index} {...other}>
      {value === index && <Box sx={{ p: 3 }}>{children}</Box>}
    </div>
  );
}

// 无障碍属性辅助函数
function a11yProps(index) {
  return {
    id: `vertical-tab-${index}`,
    'aria-controls': `vertical-tabpanel-${index}`,
  };
}

const steps = ["Shirt", "Hoodies", "Jeans", "Inner wear"];

export default function Products() {
  const [activeTab, setActiveTab] = useState(0);
  const [submitSuccess, setSubmitSuccess] = useState(false);
  // 表单ref用于收集数据
  const formRef = useRef(null);

  // Tab切换事件
  const handleTabChange = (event, newValue) => {
    setActiveTab(newValue);
    setSubmitSuccess(false);
  };

  // 下一步逻辑
  const handleNext = () => {
    // 最后一步走提交逻辑
    if (activeTab === steps.length - 1) {
      handleSubmit();
      return;
    }
    setActiveTab(prev => prev + 1);
  };

  // 返回逻辑
  const handleBack = () => {
    setActiveTab(prev => prev - 1);
    setSubmitSuccess(false);
  };

  // 重置逻辑
  const handleReset = () => {
    setActiveTab(0);
    setSubmitSuccess(false);
    formRef.current?.reset();
  };

  // 表单提交收集数据逻辑
  const handleSubmit = () => {
    const formData = new FormData(formRef.current);
    // 转成对象格式
    const formValues = Object.fromEntries(formData.entries());
    console.log("所有表单数据:", formValues);
    // 这里写你的提交接口逻辑
    setSubmitSuccess(true);
  };

  return (
    <Box sx={{ flexGrow: 1, display: 'flex' }}>
      <Tabs
        orientation="vertical"
        variant="scrollable"
        value={activeTab}
        onChange={handleTabChange}
        aria-label="Vertical tabs"
        sx={{ borderRight: 1, borderColor: 'divider', minWidth: 120 }}
      >
        <Tab label="Shirt" {...a11yProps(0)} />
        <Tab label="Hoodies" {...a11yProps(1)} />
        <Tab label="Jeans" {...a11yProps(2)} />
        <Tab label="Inner wear" {...a11yProps(3)} />
      </Tabs>

      <Box sx={{ flex: 1, paddingLeft: 2 }}>
        <form ref={formRef}>
          <TabPanel value={activeTab} index={0}>
            衬衫表单:<input name="shirtSize" placeholder="衬衫尺码" />
          </TabPanel>
          <TabPanel value={activeTab} index={1}>
            卫衣表单:<input name="hoodiesColor" placeholder="卫衣颜色" />
          </TabPanel>
          <TabPanel value={activeTab} index={2}>
            牛仔裤表单:<input name="jeansLength" placeholder="牛仔裤长度" />
          </TabPanel>
          <TabPanel value={activeTab} index={3}>
            内衣表单:<input name="innerMaterial" placeholder="内衣材质" />
          </TabPanel>
        </form>

        {/* 操作按钮区域 */}
        <Grid sx={{ marginTop: 3 }}>
          {submitSuccess ? (
            <div>
              <Typography>Saved Successfully!</Typography>
              <Button onClick={handleReset}>Reset</Button>
            </div>
          ) : (
            <div>
              <Button
                variant="contained"
                color="secondary"
                disabled={activeTab === 0}
                onClick={handleBack}
                sx={{ marginRight: 2 }}
              >
                返回
              </Button>
              <Button
                variant="contained"
                color="primary"
                onClick={handleNext}
              >
                {activeTab === steps.length - 1 ? "保存并提交" : "下一步"}
              </Button>
            </div>
          )}
        </Grid>
      </Box>
    </Box>
  );
}

表单数据获取说明

上面代码里已经内置了表单数据收集逻辑,两种常用方案适配不同场景:

  • 轻量场景直接用FormData:给外层form标签绑定ref,提交时直接实例化FormData即可读取所有表单项的值,要求你的TabPanel未激活时是hidden状态而非直接卸载DOM(上述代码里的TabPanel就是这个逻辑)
  • 复杂表单场景:在父组件统一声明所有表单字段的状态,通过props传递给对应Tab的表单项,提交时直接读取父组件的状态对象即可,不受Tab卸载逻辑影响

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.04 11:18:04