React中如何根据输入值实现array.map的条件渲染?
问题与解决方案
问题描述
我的模态框包含三个输入控件:两个下拉框(field、operator)和一个文本输入框(operand)。需求是当operator下拉框选中“is empty”时,隐藏operand输入框,仅保留前两个控件。
尝试用useState控制隐藏逻辑时,不仅未生效,还导致field下拉框无法选择选项。原代码如下:
render () { const { filterInputs = [] } = this.props; filterInputs.forEach((filterInput, i) => { this[`filter`] = React.createRef(); }); const filteredLevels = filterInputs.map((filterInput, i) => ( <div className="align-items-center" key={i}> <InputElement {...filterInput.field} onChange={this.onFilterChange} /> <InputElement {...filterInput.operator} onChange={this.onFilterChange} /> <InputElement {...filterInput.operand} onChange={this.onFilterChange} refInst={this[`filter`]} /> </div> )); return ( <Fragment> {filteredLevels} </Fragment> ); }
问题原因与修复方案
- 类组件误用Hook:当前代码是类组件(使用
render()和this.props),不能直接使用useState,类组件需通过this.state管理状态。 - 状态管理缺失:未维护每个filter项的operator选中状态,无法根据当前值判断是否隐藏operand。
- 事件逻辑混乱:
onFilterChange未区分当前操作的控件类型,导致状态更新错误。
修改后的完整代码
import React, { Fragment, Component } from 'react'; class FilterModal extends Component { constructor(props) { super(props); // 初始化状态,存储每个filter项的operator选中值 this.state = { operators: props.filterInputs.map(input => input.operator.value || '') }; // 绑定事件处理函数 this.onFilterChange = this.onFilterChange.bind(this); } onFilterChange(e, index) { const { name, value } = e.target; const { operators } = this.state; // 仅当是operator控件变化时,更新对应项的状态 if (name === 'operator') { // 替换为实际operator控件的name属性值 const newOperators = [...operators]; newOperators[index] = value; this.setState({ operators: newOperators }); } // 其他输入控件的原有处理逻辑保留 // ... } render() { const { filterInputs = [] } = this.props; const { operators } = this.state; const filteredLevels = filterInputs.map((filterInput, i) => ( <div className="align-items-center" key={i}> <InputElement {...filterInput.field} onChange={(e) => this.onFilterChange(e, i)} /> <InputElement {...filterInput.operator} value={operators[i]} onChange={(e) => this.onFilterChange(e, i)} /> {/* 根据当前operator值条件渲染operand */} {operators[i] !== 'is empty' && ( <InputElement {...filterInput.operand} onChange={(e) => this.onFilterChange(e, i)} refInst={this[`filter${i}`]} {/* 修正ref,避免循环覆盖 */} /> )} </div> )); return ( <Fragment> {filteredLevels} </Fragment> ); } }
关键修改说明
- 状态初始化:在
constructor中创建operators数组,对应每个filter项的operator选中值,确保状态独立。 - 事件传递索引:
onFilterChange接收当前项的索引,精准更新对应位置的operator状态。 - 条件渲染:通过
operators[i] !== 'is empty'判断,仅在选中值不为“is empty”时渲染operand输入框。 - 修正ref存储:将
this[filter]改为this[filter${i}],避免循环中ref被覆盖,确保每个控件ref独立。
内容的提问来源于stack exchange,提问作者susmariosep
相关产品推荐
相关产品推荐

