如何在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
相关产品推荐
相关产品推荐

