[英]React router v6 how to use `navigate` redirection in axios interceptor
[英]How to use pagination with React router v6
我正在尝试使用反应路由器 v6 实现分页。 分页本身正在工作,但每次刷新页面时都会返回第 1 页。我想在 url 中有分页号。 在这里它适用于第 1 页,但它不会在单击下一步按钮时更新页码。 我该如何解决这个问题?
这是我的代码:
function PostsList({ page, setPage }) {
// Get data
const [allPosts, setAllPosts] = useState([])
const [pages, setPages] = useState(0)
useEffect(() => {
axios
.get("/posts/posts")
.then(res => {
setAllPosts(res.data)
setPages(Math.round(res.data.length / dataLimit))
})
.catch(err => console.log(err))
}, [])
// Pagination
const dataLimit = 10
const [currentPage, setCurrentPage] = useState(page)
const goToNextPage = () => {
setCurrentPage(page => page + 1)
setPage(page => page + 1)
}
const goToPreviousPage = () => {
setCurrentPage(page => page - 1)
setPage(page => page - 1)
}
const changePage = e => {
const pageNumber = Number(e.target.textContent)
setCurrentPage(pageNumber)
}
const getPaginatedData = () => {
const startIndex = currentPage * dataLimit - dataLimit
const endIndex = startIndex + dataLimit
return allPosts.slice(startIndex, endIndex)
}
const getPaginationGroup = () => {
let start = Math.floor((currentPage - 1) / pages) * pages
return new Array(pages).fill().map((_, i) => start + i + 1)
}
return (
<Page>
<ListPosts>
{getPaginatedData().map(post => (
<Card post={post} key={post._id} />
))}
</ListPosts>
{getPaginationGroup().length > 0 && (
<PaginationContainer>
<PaginationButton
onClick={goToPreviousPage}
disabled={currentPage === 1 && "disabled"}
>
<Icon
name="chevron-left"
color="currentColor"
size={16}
/>
</PaginationButton>
{getPaginationGroup().map((item, i) => (
<PaginationButton
onClick={changePage}
className={currentPage === item && "active"}
key={i}
>
{item}
</PaginationButton>
))}
<PaginationButton
onClick={goToNextPage}
disabled={currentPage === pages && "disabled"}
>
<Icon
name="chevron-right"
color="currentColor"
size={16}
/>
</PaginationButton>
</PaginationContainer>
)}
</Page>
)
}
export default PostsList
和路线:
function Switch() {
const [page, setPage] = useState(1)
return (
<Routes>
<Route
exact
path="/posts/:page"
element={<PostsList page={page} setPage={setPage} />}
/>
</Routes>
)
}
export default Switch
谢谢你的帮助!
您正在复制您的路线 state,方法是将其保存在本地组件 state 中,并且仅更新本地组件 state。 相反,请确保使用路由作为您的路由 state 的真实来源,并使用编程路由和链接组件等工具来更新您的页面 state。
function Switch() {
return (
<Routes>
<Route
exact
{/* :page here the "state" of the route, we don't need to duplicate it. */}
path="/posts/:page"
element={<PostsList />}
/>
</Routes>
)
}
export default Switch
有关编程导航的详细信息,请参阅: https://reactrouter.com/docs/en/v6/hooks/use-navigate ,
function PostsList() {
// Get data
const [allPosts, setAllPosts] = useState([])
const [pages, setPages] = useState(0)
useEffect(() => {
axios
.get("/posts/posts")
.then(res => {
setAllPosts(res.data)
setPages(Math.round(res.data.length / dataLimit))
})
.catch(err => console.log(err))
}, [])
// Pagination
const dataLimit = 10
const { page: currentPage } = useParams(); // from react-router, this is the `:page` parameter defined on the route.
const navigate = useNavigate();
const goToNextPage = () => {
navigate(`../${currentPage + 1}`) // you may have to tweak this based on your routing. See the link above about useNavigate()
}
const goToPreviousPage = () => {
navigate(`../${currentPage - 1}`)
}
const changePage = e => {
const pageNumber = Number(e.target.textContent)
navigate(`../${pageNumber}`)
}
const getPaginatedData = () => {
const startIndex = currentPage * dataLimit - dataLimit
const endIndex = startIndex + dataLimit
return allPosts.slice(startIndex, endIndex)
}
const getPaginationGroup = () => {
let start = Math.floor((currentPage - 1) / pages) * pages
return new Array(pages).fill().map((_, i) => start + i + 1)
}
return (
<Page>
<ListPosts>
{getPaginatedData().map(post => (
<Card post={post} key={post._id} />
))}
</ListPosts>
{getPaginationGroup().length > 0 && (
<PaginationContainer>
<PaginationButton
disabled={currentPage === 1 && "disabled"}
>
<NavLink to={`../${currentPage - 1}`}> // This might need to change slightly based on your needs, or could use the programatic approach above. Same for the other buttons below.
<Icon
name="chevron-left"
color="currentColor"
size={16}
/>
</NavLink>
</PaginationButton>
{getPaginationGroup().map((item, i) => (
<PaginationButton
className={currentPage === item && "active"}
key={i}
>
{item}
</PaginationButton>
))}
<PaginationButton
disabled={currentPage === pages && "disabled"}
>
<Icon
name="chevron-right"
color="currentColor"
size={16}
/>
</PaginationButton>
</PaginationContainer>
)}
</Page>
)
}
export default PostsList
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.