React项目react-virtualized表格滚动时页码更新过快引发API异常怎么解决
解决方案
核心原因
async/await只能阻塞单个函数内部的执行流程,无法阻止高频触发的滚动事件生成新的独立执行上下文,所以你的等待逻辑完全拦不住重复请求。另外你目前的滚动触发逻辑存在两个错误:
- 没有判断滚动位置,只要滚动就触发翻页,远早于实际需要加载下一页的时机
- onScroll回调的传参写法错误,丢失了react-virtualized返回的滚动位置参数,无法做底部判断
具体修复步骤
1. 修正onScroll传参写法
将Table组件的onScroll属性修改为直接传入handleScroll,拿到官方返回的滚动参数:
<StyledTable height={250} width={this.props.width} headerHeight={headerHeight} rowHeight={rowHeight} rowRenderer={this.rowRenderer} rowCount={this.props.codeSets.length} rowGetter={({ index }) => this.props.codeSets[index]} LoadingRow={this.props.LoadingRow} overscanRowCount={5} tabIndex={-1} className='ui very basic small single line striped table' columnsList={columns} onScroll={this.handleScroll} />
2. 新增三层拦截逻辑
在组件内新增请求锁、滚动底部判断、页码上限判断三个拦截条件,避免无效请求:
- 在constructor中初始化请求锁实例属性:
constructor(props) { super(props); this.isLoading = false; // 其余初始化逻辑 }
- 修改handleScroll逻辑:
handleScroll = async ({ scrollTop, scrollHeight, clientHeight }) => { // 命中任意拦截条件直接终止执行 if ( this.isLoading // 请求进行中直接拦截 || scrollTop + clientHeight < scrollHeight - 100 // 未滚动到距离底部100px的阈值不触发 || this.props.page_num >= this.props.totalPage // 已到最大页码不触发,totalPage为接口返回的总页数,存在全局状态中 ) return; if (this.props.masterName && this.props.codeSystem) { this.isLoading = true; const nextPage = this.props.page_num + 1; const params = { code_system_category_id: this.props.masterName, code_systems_id: this.props.codeSystem, page_num: nextPage, ...(this.props.entityName && { entity_name: this.props.entityName }), ...(this.props.status && { status: this.props.status }) }; try { await this.props.setPageNumber(nextPage); await this.props.fetchCodeSets(params); } catch (err) { console.error('列表加载失败', err); } finally { // 无论请求成功失败都重置锁 this.isLoading = false; } } }
3. 补充总页码逻辑
调用fetchCodeSets拿到接口返回后,将接口返回的总页数/总条数存入全局状态,作为页码上限的判断依据。如果接口返回空数组,也可以直接将当前页码标记为最大页码,停止后续请求。
内容的提问来源于stack exchange,提问作者rudeTool
相关产品推荐
相关产品推荐

