React自动补全场景下如何根据responseData索引和长度动态切换按钮
问题根因
你修改的numRows是onChangeCaptureItem函数内的临时变量,没有存入组件state,render函数每次执行都会重新基于currentItem计算numRows,所以你对临时变量的修改完全不会触发渲染更新。
修复方案
1. 废弃手动维护numRows的逻辑
numRows是完全可以通过currentItem派生的状态,不需要单独维护,只要currentItem的数据符合预期,渲染长度会自动更新。
2. 修正新增行逻辑
你要加新的空行,直接调用已经实现的addFormFields方法即可,该方法会自动往currentItem里新增一个空条目,触发渲染后就会出现新的带Add按钮的行。
3. 修正onChangeCaptureItem逻辑
新增行的触发时机是:用户在最后一行的自动补全选中了有效值,而不是value为null的时候。修正后的代码如下:
onChangeCaptureItem = i => (event, value) => { const currentItem = [...this.state.currentItem]; // 更新当前行的选中值 currentItem[i].itemNo = value; this.setState({ currentItem }, () => { // 只有当前操作的是最后一行、且用户选中了有效值时,才新增空行 const isLastRow = i === currentItem.length - 1; if (isLastRow && value !== null) { this.addFormFields(); } }); }
4. 渲染按钮的逻辑调整
渲染每行的按钮时,直接通过当前行的位置和值判断显示Add还是Remove即可,不需要依赖额外状态:
render(){ const CurrentItemToRender = this.state.currentItem.filter(ca => ca.itemNo); return CurrentItemToRender.map((item, index) => ( <div key={index}> {/* 原有自动补全组件逻辑保留 */} <Autocomplete value={item.itemNo} onChange={this.onChangeCaptureItem(index)} /> {/* 按钮逻辑:最后一行且值为空显示Add,其余显示Remove */} {index === CurrentItemToRender.length - 1 && !item.itemNo ? ( <button>Add</button> ) : ( <button onClick={() => this.removeRow(index)}>Remove</button> )} </div> )) }
5. 优化searchItem方法避免多次渲染
原有方法在循环内多次调用setState会触发多次不必要的渲染,建议合并状态更新:
async searchItem() { try { const response = await getItem(this.state.currentItem[0].parentItemNo); if (response.ok) { const responseData = await response.json(); this.removeAllFields(0); const newItemList = []; const parentNo = this.state.currentItem[0].parentItemNo; Object.values(responseData).forEach(itemNo => { // 提前过滤掉和父级编号相同的条目,避免新增后再删除 if (itemNo !== parentNo) { newItemList.push({ itemNo, parentItemNo: parentNo }) } }); // 末尾新增一个空行用于后续添加 newItemList.push({ itemNo: null, parentItemNo: parentNo }) // 一次性更新所有状态,只触发一次渲染 this.setState({ currentItem: newItemList, searchMode: true, addRow: true }) } } catch (err) { console.error('条目查询失败', err) } }
内容的提问来源于stack exchange,提问作者Sarahrb
相关产品推荐
相关产品推荐

