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

如何在ReactJS循环生成的表单列表中启用/禁用对应行表单元素?

实现下拉选Date时禁用对应行的Values输入框

要实现这个需求,核心是让每行的下拉选择框和输入框状态联动,确保每行的状态独立不互相影响,下面提供两种常用方案:


方案一:父组件统一管理状态(适合需要统一收集数据的场景)

1. 父组件维护状态

在循环生成行的父组件中,用一个对象存储每行的选中类型,键为每行的唯一标识(type+key):

import { useState, useEffect } from 'react';

const ParentComponent = () => {
  // 存储每行的选中类型,键是`type+key`
  const [rowTypes, setRowTypes] = useState({});

  // 初始化默认值(如果有预设的defaultValues)
  useEffect(() => {
    // 假设你的默认行数据是defaultRows数组,示例:
    // defaultRows.forEach(item => {
    //   const rowKey = `${item.type}${item.key}`;
    //   setRowTypes(prev => ({ ...prev, [rowKey]: item.defaultValues?.type || 'single' }));
    // });
  }, []);

  // 更新指定行的选中类型
  const handleTypeChange = (rowKey, selectedType) => {
    setRowTypes(prev => ({
      ...prev,
      [rowKey]: selectedType
    }));
  };

  // 循环生成行
  return (
    <Form>
      {yourDataArray.map((item, index) => {
        const rowKey = `${item.type}${index}`;
        return getRow(
          item.type,
          index,
          item.defaultValues,
          rowTypes[rowKey],
          handleTypeChange
        );
      })}
    </Form>
  );
};

2. 修改getRow函数

新增参数接收当前行的选中类型和状态更新回调,给输入框添加disabled判断:

const getRow = (type, key, defaultValues = {}, currentType, onTypeChange) => {
  const rowKey = `${type}${key}`;
  
  return (
    <Row className="mb-3" key={rowKey}>
      <Col xs={3}>
        <Form.Group>
          <Form.Label>Name</Form.Label>
          <Form.Control
            name={`${type}name${key}`}
            className={`${type}name`}
            defaultValue={defaultValues?.name || null}
            type="text"
          />
        </Form.Group>
      </Col>
      <Col>
        <Form.Group>
          <Form.Label>Values</Form.Label>
          <Form.Control
            name={`${type}value${key}`}
            className={`${type}value`}
            defaultValue={defaultValues?.value || null}
            type="text"
            // 选中Date时禁用输入框
            disabled={currentType === 'date'}
          />
        </Form.Group>
      </Col>
      <Col xs={3}>
        <Form.Group>
          <Form.Label>Type</Form.Label>
          <Form.Select
            name={`${type}type${key}`}
            className={`${type}type`}
            defaultValue={defaultValues?.type || 'single'}
            onChange={(e) => onTypeChange(rowKey, e.target.value)}
          >
            <option value="single">Single</option>
            <option value="multi">Multi</option>
            <option value="date">Date</option>
          </Form.Select>
        </Form.Group>
      </Col>
    </Row>
  );
};

方案二:将行封装为独立子组件(适合无需父组件干预的简单场景)

把每行做成独立组件,内部维护自己的选中状态,不需要父组件管理:

const FormRow = ({ type, key: rowKey, defaultValues = {} }) => {
  // 组件内部维护选中类型状态
  const [selectedType, setSelectedType] = useState(defaultValues?.type || 'single');

  return (
    <Row className="mb-3" key={`${type}${rowKey}`}>
      <Col xs={3}>
        <Form.Group>
          <Form.Label>Name</Form.Label>
          <Form.Control
            name={`${type}name${rowKey}`}
            className={`${type}name`}
            defaultValue={defaultValues?.name || null}
            type="text"
          />
        </Form.Group>
      </Col>
      <Col>
        <Form.Group>
          <Form.Label>Values</Form.Label>
          <Form.Control
            name={`${type}value${rowKey}`}
            className={`${type}value`}
            defaultValue={defaultValues?.value || null}
            type="text"
            disabled={selectedType === 'date'}
          />
        </Form.Group>
      </Col>
      <Col xs={3}>
        <Form.Group>
          <Form.Label>Type</Form.Label>
          <Form.Select
            name={`${type}type${rowKey}`}
            className={`${type}type`}
            defaultValue={defaultValues?.type || 'single'}
            onChange={(e) => setSelectedType(e.target.value)}
          >
            <option value="single">Single</option>
            <option value="multi">Multi</option>
            <option value="date">Date</option>
          </Form.Select>
        </Form.Group>
      </Col>
    </Row>
  );
};

// 父组件中使用
const ParentComponent = () => {
  return (
    <Form>
      {yourDataArray.map((item, index) => (
        <FormRow
          key={`${item.type}${index}`}
          type={item.type}
          key={index}
          defaultValues={item.defaultValues}
        />
      ))}
    </Form>
  );
};

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 03:55:22