React分页问题:如何在无下页数据时禁用Next按钮
解决React分页组件Next按钮禁用问题
我来帮你搞定这个问题!其实你完全不需要从render()里获取pageNumbers.length,因为总页数可以直接通过你的props和state计算出来——就是Math.ceil(this.props.contacts.length / this.state.todosPerPage)。我们可以用这个值来判断是否已经到了最后一页,从而禁用Next按钮。
具体修改步骤:
1. 先计算总页数
在render()方法里先算出总页数,方便后续判断:
render() { const characters = this.props.contacts; const { currentPage, todosPerPage } = this.state; // 计算总页数 const totalPages = Math.ceil(characters.length / todosPerPage); // 其他原有代码... }
2. 修改Next按钮的渲染逻辑
根据当前页是否等于总页数,动态添加disabled类,并控制点击事件是否生效:
<li onClick={() => { // 只有当前页小于总页数时才执行翻页 if (currentPage < totalPages) { this.increment(); } }} // 当是最后一页时添加disabled类(Bootstrap会自动置灰并禁用点击) className={`page-item ${currentPage >= totalPages ? 'disabled' : ''}`} > <a className="page-link" aria-label="Next"> <span aria-hidden="true">»</span> <span className="sr-only">Next</span> </a> </li>
注意:这里我把原来的
page-link类移到了内部的<a>标签上,外层<li>用page-item,这是Bootstrap分页组件的正确结构,避免样式错乱。
3. 优化你的increment函数(可选但推荐)
为了更严谨,即使按钮被点击(比如用户通过控制台强制触发),我们也可以在increment函数里再做一次判断:
increment = () => { const { currentPage, todos todosPerPage } = this.state; const totalPages = Math.ceil(this.props.contacts.length / todosPerPage); if (currentPage < totalPages) { this.setState(prevState => ({ currentPage: prevState.currentPage + 1 })); } }
4. 顺便修复页码渲染的小问题
你当前的renderPageNumbers代码会为每个页码生成一个独立的<nav>和<ul>,这会导致页面上出现多个分页条。应该把<nav>和<ul>放在map外面:
const renderPageNumbers = ( <nav aria-label="Page navigation example"> <ul className="pagination justify-content-center"> {pageNumbers.map(number => ( <li className="page-item" key={number}> <button className="page-link" id={number} onClick={() => this.handleClick(number)} > {number} </button> </li> ))} </ul> </nav> );
完整修改后的render()方法参考:
render() { const characters = this.props.contacts; const { currentPage, todosPerPage } = this.state; const totalPages = Math.ceil(characters.length / todosPerPage); const indexOfLastTodo = currentPage * todosPerPage; const indexOfFirstTodo = indexOfLastTodo - todosPerPage; const currentTodos = characters.slice(indexOfFirstTodo, indexOfLastTodo); const renderTodos = currentTodos.map((character, index) => { return ( <div className="col-md-2" key={index}> <img src={character.image} className="img-thumbnail" alt={character.name} /> <div className="content"> <h6 className="header">{character.name}</h6> <h6 className="header">status: {character.status}</h6> <h6 className="header">species: {character.species}</h6> </div> </div> ); }); const pageNumbers = []; for (let i = 1; i <= totalPages; i++) { pageNumbers.push(i); } const renderPageNumbers = ( <nav aria-label="Page navigation example"> <ul className="pagination justify-content-center"> {pageNumbers.map(number => ( <li className="page-item" key={number}> <button className="page-link" id={number} onClick={() => this.handleClick(number)} > {number} </button> </li> ))} </ul> </nav> ); return ( <nav aria-label="Page navigation example"> <div className="container"> <div className="row"> {renderTodos} </div> </div> <ul className="pagination justify-content-center"> <li onClick={() => currentPage > 1 && this.decrement()} className={`page-item ${currentPage <= 1 ? 'disabled' : ''}`} > <a className="page-link" aria-label="Previous"> <span aria-hidden="true">«</span> <span className="sr-only">Previous</span> </a> </li> {/* 这里注意:原来的renderPageNumbers已经包含了nav和ul,所以直接渲染即可 */} {renderPageNumbers} <li onClick={() => currentPage < totalPages && this.increment()} className={`page-item ${currentPage >= totalPages ? 'disabled' : ''}`} > <a className="page-link" aria-label="Next"> <span aria-hidden="true">»</span> <span className="sr-only">Next</span> </a> </li> </ul> </nav> ); }
这样修改后,当没有下一页时,Next按钮会自动置灰,并且点击不会触发翻页逻辑,完美解决你的问题!
内容的提问来源于stack exchange,提问作者Michal
相关产品推荐
相关产品推荐

