React分页组件Paging重复执行 点击页码选中状态滞后1步如何解决
根因分析
setState本身是异步执行的,你在调用setState后立即执行fetchApi,此时currentPage状态还未完成更新,fetchApi拿到的仍是上一次的旧页码,所以接口返回的分页数据里的active标记还是旧页码,最终渲染出来的高亮状态自然不符合预期。- Paging 组件的
onClick回调参数命名错误,将事件对象命名为index,属于易引发后续bug的坏代码。 - 直接把整个父组件实例、完整state传给子组件属于不合理的传参设计,容易引发不可预期的引用问题。
- 用map的index作为列表key,属于性能和稳定性都较差的实践。
修复方案
- 调整
handleClick的执行顺序,把fetchApi放到setState的回调函数中,保证状态更新完成后再发起请求:
handleClick(event) { let currentPage = Number(event.target.id) localStorage.setItem("currentPage", currentPage) this.setState ({ currentPage: currentPage }, () => { // 等待currentPage状态更新完成后再调用接口 this.fetchApi() }) }
- 修复Paging组件的错误写法:
- 修正
onClick的参数命名,避免歧义 - 用唯一的页码作为列表key,代替map的index
function Paging(props) { const apiPaging = props.apiPaging const apiPagingSliced = apiPaging.slice(1, -1) const renderPageNumbers = apiPagingSliced.map((links) => { return <button key={links.label} id={links.label} onClick={(e)=>props.handleClick(e)} className={links.active ? "mark-page" : ""} >{links.label} </button> }) return ( <div id = "page-nums"> {renderPageNumbers} </div> ) }
- 调整父组件给Paging的传参,只传必要的字段,不要传整个state和父组件实例:
return( <div> <Paging apiPaging={this.state.apiPaging} handleClick={this.handleClick} /> </div> )
内容的提问来源于stack exchange,提问作者user14964079
相关产品推荐
相关产品推荐

