React中实现点击对应Line按钮在其下方添加子字段的问题
解决React组件中子元素对应父元素渲染的问题
我明白你的问题啦——现在你点击不同Line旁的按钮,所有新增的字段都堆在最后,没法对应到各自的Line下面对吧?核心问题是你现在用了一个全局的addField数组来存所有字段,导致渲染的时候全放在一起了。咱们得改成让每一条Line自己管理属于它的字段,这样点击哪个Line的按钮,字段就加在哪个Line下面。
具体修改方案
- 重构state结构
把原来分散的count、addLine、addField改成一个lines数组,每个元素是包含当前Line ID和对应字段列表的对象,这样每条Line的字段数据都和自身绑定在一起:
state = { count: 0, tableName: "", fieldName:"", tables: [], fields: [], lines: [] // 新的state结构,每个元素是 { id: number, fields: number[] } };
- 修改添加Line的方法
不再单独维护addLine数组,直接往lines里push新的Line对象:
addNewLine = event => { event.preventDefault(); const newLineId = this.state.lines.length + 1; this.setState(prevState => ({ lines: [...prevState.lines, { id: newLineId, fields: [] }] })); };
- 新增对应Line添加字段的方法
需要接收点击的Line ID,找到对应的Line并给它的fields数组添加新元素:
addFieldToLine = (lineId, event) => { event.preventDefault(); this.setState(prevState => ({ lines: prevState.lines.map(line => { if (line.id === lineId) { const newFieldId = line.fields.length + 1; return { ...line, fields: [...line.fields, newFieldId] }; } return line; }) })); };
- 调整render逻辑
遍历lines数组,每条Line渲染完成后,紧接着遍历它自身的fields数组,把字段渲染在这条Line的下方:
render() { const { tableName, fieldName, lines } = this.state; return ( <React.Fragment> <div className="form-wrapper"> <div className="row"> <div className="col-10 container"> <form className="card"> <div className="card-header"> <h3 className="card-title"> Criteria Set </h3> </div> <div className="card-body"> <div className="row"> <div className="col-md-7 col-lg-8"> <div className="add-line"> <Button icon labelPosition="left" onClick={this.addNewLine} > Add Line <Icon name="plus" /> </Button> {/* 遍历每条Line */} {lines.map(line => ( <div key={line.id} className="field-line" style={{ marginTop: "30px" }}> <h4 className="field-button">Line {line.id}</h4> <Button className="field-button" icon onClick={(e) => this.addFieldToLine(line.id, e)} > <Icon name="box" /> </Button> {/* 遍历当前Line的字段,渲染在Line下方 */} {line.fields.map(fieldId => ( <React.Fragment key={fieldId}> <div className="field-button" style={{ marginTop: "20px", paddingLeft: "20px" }}> <h4 className="field-button"> <span> table.field </span> </h4> <Button className="field-button" icon> <Icon name="delete calendar" /> </Button> </div> <br /> </React.Fragment> ))} </div> ))} </div> </div> </div> </div> </form> </div> </div> </div> </React.Fragment> ); }
关键说明
- 现在每条Line的字段数据都存在自身的
fields数组里,点击对应Line的按钮时,只会修改这条Line的字段列表 - 渲染时字段紧跟在所属Line的后面,完美解决了"字段跳转到最后一行"的问题
- 代码里还保留了删除按钮的位置,你可以后续补充删除字段的逻辑(根据
lineId和fieldId找到对应项删除即可)
内容的提问来源于stack exchange,提问作者Azeez Oluwasegun Akinsola
相关产品推荐
相关产品推荐

