React-Pagination实现表格默认按序号排序问题求助
问题描述
我有一个表格,需要让它默认按第一列的数字1、2、3……排序,当前使用React-Pagination组件。我四处查找资料,但找到的都是点击按钮触发排序的方案,希望有人能帮助我或指明解决方向。
以下是我的代码:
import axios from "axios"; import React, { useState, useEffect } from "react"; import Pagination from "https://cdn.skypack.dev/rc-pagination@3.1.15"; const News = () => { const [playerName, setPlayerName] = useState([]); const [playerRank, setPlayerRank] = useState([]); const [player, setPlayer] = useState([]); const [perPage, setPerPage] = useState(10); const [size, setSize] = useState(perPage); const [current, setCurrent] = useState(1); const [players, setPlayers] = useState(); const fetchData = () => { const playerAPI = 'http://localhost:3008/api/players'; const playerRank = 'http://localhost:3008/api/highscore/players'; const getINFOPlayer = axios.get(playerAPI) const getPlayerRank = axios.get(playerRank) axios.all([getINFOPlayer, getPlayerRank]).then( axios.spread((...allData) => { const allDataPlayer = allData[0].data.players const getINFOPlayerRank = allData[1].data.players const newPlayer = allDataPlayer.map(name => { const pr = getINFOPlayerRank.find(rank => name.id === rank.id) return { id: name.id, name: name.name, status: name.status, position: pr?.position, score: pr?.score } // or simply do the following if the keys doesn't matter: return {...name, ...pr} }) setPlayerName(allDataPlayer) setPlayerRank(getINFOPlayerRank) console.log(newPlayer) setPlayer(newPlayer) }) ) } useEffect(() => { fetchData() }, []) const PerPageChange = (value) => { setSize(value); const newPerPage = Math.ceil(players.length / value); if (current > newPerPage) { setCurrent(newPerPage); } } const getData = (current, pageSize) => { // Normally you should get the data from the server return player?.slice((current - 1) * pageSize, current * pageSize); }; const sortData = getData && player?.sort((a, b) => a.position > b.position ? 1 : -1) const PaginationChange = (page, pageSize) => { setCurrent(page); setSize(pageSize) } const PrevNextArrow = (current, type, originalElement) => { if (type === 'prev') { return <button><i className="fa fa-angle-double-left"></i></button>; } if (type === 'next') { return <button><i className="fa fa-angle-double-right"></i></button>; } return originalElement; } return ( <> <div className="container-fluid mt-5 mb-5"> <div className="row justify-content-center"> <div className="col-md-10"> <div className="card"> <div className="card-body p-0"> <div className="table-filter-info"> <Pagination className="pagination-data" showTotal={(total, range) => `Showing ${range[0]}-${range[1]} of ${total}`} onChange={PaginationChange} total={player.length} current={current} pageSize={size} showSizeChanger={false} itemRender={PrevNextArrow} onShowSizeChange={PerPageChange} /> </div> <div className="table-responsive"> <table className="table table-text-small mb-0"> <thead className="thead-primary table-sorting"> <tr> <th>#</th> <th>Name</th> <th>Points</th> <th>Alliance</th> <th>Status</th> </tr> </thead> <tbody> {getData(current, size) .map((player) => { return ( <tr key={player.name}> <td>{player.position}</td> <td>{player.name}</td> <td>{player.score}</td> <td>{player.alliance}</td> <td>{player.status}</td> </tr> ); })} </tbody> </table> </div> <div className="table-filter-info"> <Pagination className="pagination-data" showTotal={(total, range) => `Showing ${range[0]}-${range[1]} of ${total}`} onChange={PaginationChange} total={player.length} current={current} pageSize={size} showSizeChanger={false} itemRender={PrevNextArrow} onShowSizeChange={PerPageChange} /> </div> </div> </div> </div> </div> </div> </> ) } export default News
解决方案
要实现表格默认按第一列(position)数字排序,不需要额外点击触发,只需在数据处理阶段完成排序即可,以下是具体修改步骤:
1. 在数据合并后直接排序
原代码中sortData变量未实际生效,且Array.sort()会原地修改数组,建议在合并完玩家数据后立即排序,再存入状态:
const fetchData = () => { const playerAPI = 'http://localhost:3008/api/players'; const playerRank = 'http://localhost:3008/api/highscore/players'; const getINFOPlayer = axios.get(playerAPI) const getPlayerRank = axios.get(playerRank) axios.all([getINFOPlayer, getPlayerRank]).then( axios.spread((...allData) => { const allDataPlayer = allData[0].data.players const getINFOPlayerRank = allData[1].data.players const newPlayer = allDataPlayer.map(name => { const pr = getINFOPlayerRank.find(rank => name.id === rank.id) return { id: name.id, name: name.name, status: name.status, position: pr?.position, score: pr?.score, alliance: name.alliance // 补充原代码缺失的alliance字段 } }) // 新增排序逻辑:按position升序,处理position不存在的情况 const sortedPlayers = [...newPlayer].sort((a, b) => { if (a.position === undefined) return 1; if (b.position === undefined) return -1; return a.position - b.position; }); setPlayerName(allDataPlayer) setPlayerRank(getINFOPlayerRank) setPlayer(sortedPlayers) // 存入排序后的数组 }) ) }
2. 移除无效代码
删除原代码中未生效的sortData变量:
// 删掉此行 const sortData = getData && player?.sort((a, b) => a.position > b.position ? 1 : -1)
3. 修正分页数据逻辑
因为状态中的player已经是排序好的数组,getData可以直接使用原逻辑,分页展示的内容会自动按顺序排列。
另外注意:原代码表格的Alliance列用到了player.alliance,但之前合并数据时未赋值,需要在返回的对象中补充alliance: name.alliance,否则该列会显示undefined。
内容的提问来源于stack exchange,提问作者yandry santana
相关产品推荐
相关产品推荐

